【问题标题】:How to test static java methods in groovy SPOCK framework?如何在 groovy SPOCK 框架中测试静态 java 方法?
【发布时间】:2016-09-27 13:05:29
【问题描述】:

我正在尝试使用 Maven 在 SPOCK groovy 框架中测试静态 java 方法。

这里是java类

  public class DataController {

 private DataInterface userService;

    public void setUserService(DataInterface userService) {
        this.userService = userService;
    }
   public static int addNumber(){
        int a = 10;
        int b = 20;
        return a+b;
    }   
 }

这里是 groovy 中的 SPOCK 测试

@PrepareForTest([DataController.class])
class BasicMockStaticTest extends Specification {

@Rule PowerMockRule powerMockRule = new PowerMockRule();

    def "When mocking static"() {
        setup :
            PowerMockito.mockStatic(DataController.class)

        when :
            Mockito.when(DataController.addNumber()).thenReturn(30);

        then :
            DataController.addNumber() == 30
    }
 }

和 POM 文件 sn-p

   <dependencies>
    <!-- Spock Framework basic dependencies: -->
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.3.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.spockframework</groupId>
        <artifactId>spock-core</artifactId>
        <!-- The version have to be compatible with Groovy -->
        <version>1.0-groovy-2.3</version>
        <scope>test</scope>
    </dependency>
    <!-- To use Hamcrest matchers: -->
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-core</artifactId>
        <version>1.3</version>
        <scope>test</scope>
    </dependency>
    <!-- To mock classes: -->
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib-nodep</artifactId>
        <version>3.1</version>
        <scope>test</scope>
    </dependency>
    <!-- Use with cglib to mock classes without default constructor: -->
    <dependency>
        <groupId>org.objenesis</groupId>
        <artifactId>objenesis</artifactId>
        <version>2.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
  <groupId>org.codehaus.gmavenplus</groupId>
  <artifactId>gmavenplus-plugin</artifactId>
  <version>1.5</version>
 </dependency>
 <!-- Power mock dependencies -->
 <dependency>
 <groupId>org.powermock</groupId>
 <artifactId>powermock-module-junit4</artifactId>
 <version>1.5.4</version>
 <scope>test</scope>
 </dependency>

 <dependency>
 <groupId>org.powermock</groupId>
 <artifactId>powermock-module-junit4-rule</artifactId>
 <version>1.5.4</version>
 <scope>test</scope>
 </dependency>

<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-classloading-xstream</artifactId>
<version>1.5.4</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
    <testSourceDirectory>E:\Workspace\Mars\rg\Spock\src\test\groovy</testSourceDirectory>
<pluginManagement>
    <plugins>
        <!-- GMavenPlus plugin -->
        <plugin>
            <groupId>org.codehaus.gmavenplus</groupId>
            <artifactId>gmavenplus-plugin</artifactId>
            <version>1.5</version>
            <executions>
                <execution>
                    <goals>
                     <goal>addSources</goal>
          <goal>addTestSources</goal>
          <goal>generateStubs</goal>
          <goal>compile</goal>
          <goal>testGenerateStubs</goal>
          <goal>testCompile</goal>
          <goal>removeStubs</goal>
          <goal>removeTestStubs</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
         <!-- Only required if names of spec classes don't match default    Surefire patterns (`*Test` etc.) -->
         <plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.6</version>
    <configuration>
      <useFile>false</useFile>
      <includes>
        <include>**/*Test*.*</include>
        <include>**/*Spec*.*</include>

      </includes>

我在 groovy 文件夹中有 4 个测试用例,其中 3 个通过了,但是这个静态方法测试给出了错误

 When mocking static(BasicMockStaticTest)  Time elapsed: 0.104 sec  <<< ERROR!
   java.lang.IllegalStateException: Extension API internal error:   org.powermock.api.extension.proxyframework.ProxyFrameworkImpl could not be  located in classpath.
    at   org.powermock.modules.junit4.rule.PowerMockClassloaderExecutor.registerProxyframework(PowerMockClassloaderExecutor.java:60)
    at  org.powermock.modules.junit4.rule.PowerMockClassloaderExecutor.forClass(PowerMoc kClassloaderExecutor.java:50)
    at org.powermock.modules.junit4.rule.PowerMockRule.apply(PowerMockRule.java:31)
at org.spockframework.runtime.extension.builtin.MethodRuleInterceptor.intercept(MethodRuleInterceptor.java:37)
at org.spockframework.runtime.extension.MethodInvocation.proceed(MethodInvocation.java:87)
at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:59)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.executeTestSet(AbstractDirectoryTestSuite.java:120)
at org.apache.maven.surefire.suite.AbstractDirectoryTestSuite.execute(AbstractDirectoryTestSuite.java:103)
at org.apache.maven.surefire.Surefire.run(Surefire.java:169)
at org.apache.maven.surefire.booter.SurefireBooter.runSuitesInProcess(SurefireBooter.java:350)
at org.apache.maven.surefire.booter.SurefireBooter.main(SurefireBooter.java:1021)

我正在运行 mvn test 来测试这些 junits ,我尝试将 cglib-nodep 的版本从 3.1 更改为 2.2.2 但没有成功。

我检查了包含 jar 文件的 java 构建路径

powermock-module-junit4-1.5.4
powermock-module-junit4-common-1.5.4
powermock-reflect-1.5.4
powermock-module-junit4-rule-1.5.4
powermock-classloading-base-1.5.4
powermock-classloading-xstream-1.5.4
powermock-api-support-1.5.4
powermock-core-1.5.4
groovy-all-2.3.1.jar
spock-core-1.0-grovy-2.3.jar

我还添加了 powermock-mockito-release-full-1.5.4,但添加后没有任何测试用例运行并且构建成功,但这不是我的意图。

我怀疑可能是缺少某些依赖项,或者某些现有依赖项存在冲突但无法继续。

谁能告诉我哪里出了问题,我可以继续测试用例,即使它失败了,我会纠正它,但我需要先删除错误。

顺便说一句,我也尝试过 groovyMock,但它为静态方法提供了空指针异常,然后我搜索并发现静态方法不适用于 groovyMock。

我已经尝试了热门博客和教程的顶级谷歌链接结果,但似乎没有一个有效。

【问题讨论】:

  • 你为什么要模拟DataController?这不是您要测试的课程吗?
  • 用 groovymock 找到了解决方案,是的,你是对的,我在嘲笑错误的课程。我需要模拟服务类,控制器正在使用服务类方法。
  • @rohitgarg 您能否发布您使用 groovymock 找到的解决方案。我试过GoovyMock(MyClass, global: true)MyClass.myStaticMethod() &gt;&gt; "mock result" 但它不起作用

标签: unit-testing groovy spock


【解决方案1】:

我在 Spock 中使用 GroovyMock 来测试静态方法(Java 中的静态方法,顺便说一句):

GroovyMock(Foo, global: true)
Foo.bar(_) >> "my-fake-result"

我还在 Spock 的测试方法中添加了这个注解, 对我的模拟不干扰其他测试:

@ConfineMetaClassChanges([Foo])  

【讨论】:

  • 这只适用于从 Groovy 类调用 Java 方法的情况。当从 Java 类调用时,Groovy 模拟的行为类似于普通的 Spock 模拟。这也被记录在案。
猜你喜欢
  • 2017-11-30
  • 1970-01-01
  • 2021-11-26
  • 2021-10-24
  • 2017-07-04
  • 1970-01-01
  • 1970-01-01
  • 2016-07-13
  • 1970-01-01
相关资源
最近更新 更多