2016-05-29 87 views
0

我想在使用Maven的SPOCK groovy框架中测试静态java方法。如何在Groovy SPOCK框架中测试静态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

@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 
    } 
} 

的SPOCK测试和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> 

我有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测试来测试这些junit,我尝试将cglib-nodep的版本从3.1更改为2.2.2,但它没有工作。

我在Java构建路径检查以下jar文件包含

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释放全-1.5.4,但补充说,没有任何的测试用例跑和构建为后成功但这不是我的意图。

我怀疑可能是一些依赖项丢失或一些现有的冲突,但无法前进。

任何人都可以告诉什么是错误的,即使它失败了,我也可以继续测试用例,我会纠正它,但我需要先删除错误。

在一个侧面说明我也尝试过groovyMock,但它给了静态方法的空指针异常,然后我搜索并发现静态方法不适用于groovyMock。

我已经尝试顶部谷歌链接结果与流行的博客和教程,但似乎没有工作。

+0

你为什么要模拟'DataController'?这不是你想测试的课程吗? – tddmonkey

+0

找到groovymock的解决方案,是的,你是对的我正在嘲笑错误的类。我需要模拟服务类,控制器使用服务类方法。 –

回答

1

我使用GroovyMock在斯波克测试静态方法(在Java静态方法,BTW):

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

我还添加了此批注中斯波克我的测试方法, 我假装不干扰其他测试:

@ConfineMetaClassChanges([Foo])