2016-10-10 184 views
0

當該類在其他Java類中使用時,Groovy測試不會爲靜態類創建模擬。下面是測試證明了這一點GroovyMock在靜態方法調用時用於測試Java類時不起作用

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 

因此,靜態方法沒有被嘲笑,實際的實現總是被調用。誰能解釋這種行爲?任何想法如何繞過這個?

Java版本:1.7.0_79,Groovy的版本:2.4.7,斯波克版本:1.0-常規-2.4,cgclib:3.1

回答

0

如果java的代碼被編譯用groovyc

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 
    } 

如果jar碼被用javac compied

1.prepare測試代碼(這個樣品是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.compile碼

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

3.execute測試

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)之間訪問和添加Stic場的方法。
因此,我創建了日誌文件來檢查「ClassWithStaticMethod#doSomething」是否從「JavaClass#方法」中調用。

+0

與之前相同的輸出,不起作用 – lolotron

+0

哦是的。你是對的... 我再次檢查。 如果使用「groovyc」編譯這些代碼(JavaClass.java和ClassWithStaticMethod.java),上述代碼將起作用。 – koji

+0

也許它需要JMockit來模擬靜態方法。 – koji

相關問題