如何在groovy SPOCK框架中测试静态java方法?

时间:2016-05-29 18:00:08

标签: unit-testing groovy spock

我正在尝试使用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文件片段

   <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但是它为静态方法提供了nullpointer异常,然后我搜索并发现静态方法不适用于groovyMock。

我尝试过热门博客和教程的google链接结果,但似乎没有效果。

1 个答案:

答案 0 :(得分:1)

我在Spock中使用GroovyMock来测试静态方法(Java中的静态方法,BTW):

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

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

@ConfineMetaClassChanges([Foo])