当前位置: 首页 > 知识库问答 >
问题:

用于测试带有静态方法调用的Java类时,GroovyMock不起作用

牟嘉
2023-03-14

当静态类在其他Java类中使用时,Groovy测试不会为该类创建模拟。下面的代码片段证明了这一点

测试中的Java类:

public class JavaClass {
    public void method() { 
      ClassWithStaticMethod.doSomething();
    }
}

带有静态方法的Java类:

public class ClassWithStaticMethod { 
    public static void doSomething() {
        System.out.println("Static method called");
    } 
}

失败的Groovy测试:

class JavaClassTest extends Specification {
  def 'test'() {
    given:
    GroovyMock(ClassWithStaticMethod, global: true)
    JavaClass javaClass = new JavaClass()

    when:
    javaClass.method()

    then:
    1 * ClassWithStaticMethod.doSomething() // <--- FAILS
  }
}
Static method called <--- original method is called, it's not mocked

Too few invocations for:

1 * ClassWithStaticMethod.doSomething()   (0 invocations)

Unmatched invocations (ordered by similarity):

None

共有1个答案

益阳平
2023-03-14
    def "foo"() {
      setup:
        // GroovyMock(ClassWithStaticMethod, global: true)
        GroovySpy(ClassWithStaticMethod, global: true)
        JavaClass javaClass = new JavaClass()

      when:
        javaClass.method()

      then:
        // 1 * ClassWithStaticMethod.doSomething()
        1 * ClassWithStaticMethod.doSomething() >> null
    }

1.准备测试代码(此示例为myspock.groovy)

// This Grabs are used for compile.
// These libraries must specifiy on class path when the file executs.
@Grapes([
  @Grab(group='org.jmockit', module='jmockit', version='1.8'),
  @Grab(group='org.spockframework', module='spock-core', version='1.0-groovy-2.4')
])

import spock.lang.*
import mockit.*

class MySpock extends Specification {

  def "hoge"() {
    setup:

    // Overwrite ClassWithStaticMethod#doSomething(static method) with JMockit/MockUp
    new MockUp<ClassWithStaticMethod>() {
      @Mock
      public static void doSomething() {
        Logger.append("abc")
      }

    }

    // Target object for this test
    JavaClass javaClass = new JavaClass()

    when: "Execute target method"
    javaClass.method()

    then: "ClassWithStaticMethod#doSomething was mocked and write the value in a file"
    Logger.count() == 1

    cleanup: "Delete log file for this test"
    Logger.delete()
  }
}

// Logging Utility for only this test.
class Logger {
  static logFile = new File("/tmp/MySpock.groovy.log")
  static append = {String msg -> logFile.append("${msg}${System.getProperty("line.separator")}")}
  static count = {logFile.readLines()?.size()?:0}
  static delete = { logFile.delete() }
}

2.编译代码

javac ClassWithStaticMethod.java&&javac JavaClass.java&&groovyc MySpock.groovy

3.执行测试

groovy -cp .:$HOME/.groovy/grapes/org.jmockit/jmockit/jars/jmockit-1.8.jar:$HOME/.groovy/grapes/org.spockframework/spock-core/jars/spock-core-1.0-groovy-2.4.jar MySpock

我第一次使用JMockit。
所以,我不知道这种用法是否正确。
我不知道在Spock和Mock(JMockit)之间相互访问和添加staic字段的方法。
因此我创建了日志文件来检查“classwithstaticmethod#doSomething”是否从“javaclass#method”调用。

 类似资料:
  • 我正在为我的项目编写junit测试用例,但我在这里面临一个问题,就是我在我的一个java类(GraphNodes.java)中使用的方法 这是我的Junit测试类 我的junit失败了,它说excepted<3>但actual<0>而且我不能将静态方法仅改为public,因为这会影响代码的某些功能,而且由于我是junit的新手,所以我不知道如何解决这一问题。所以有人能在这里帮助我吗?谢谢!!

  • 但是如果我从ClassUnderTest运行methodUnderTest: 它抛出了一个ClassWithStatic的真实实例,该实例在其实例Method中失败。

  • 问题内容: 尝试在静态类中调用非静态方法时遇到错误。 无法从类型播放中静态引用非静态方法methodName() 我不能使该方法静态,因为这也给我一个错误。 此静态方法无法从xInterface隐藏实例方法 有什么办法可以在另一个静态方法中轮回调用非静态方法?(这两种方法位于单独的包和单独的类中)。 问题答案: 从静态方法中调用非静态方法的唯一方法是使类的实例包含非静态方法。根据定义,非静态方法是

  • 我最近对 PHP 5.4 进行了更新,但收到有关静态和非静态代码的错误。 这是错误: 这是第371行: 我希望有人能帮忙。

  • Powermock为什么不模拟静态方法调用,而是在然后()语句中调用初始方法? 在这种情况下,我有一系列方法调用: TestClass方法-调用- Class4方法尝试查找上下文中不存在且挂起的对象,因此我尝试使用Powermock模拟公共静态Class3方法。 所有的类和方法都是非最终的。我使用TestNg。我的测试方法有一个@准备测试我尝试了以下方法来模拟方法调用: 或而不是当-然后返回: 或