java – Spock与Mockito测试Kotlin课程
作者:互联网
我有一些用Spock编写的测试,它涵盖了我的Java代码.现在我迁移到Kotlin,问题是我无法模拟最终类,所以我决定使用这里描述的Mockito插件:https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#unmockable
问题是我需要更换每个’_”>>’与Mockitos的any(),anyString(),when(),then()等?我试图用Mockito模拟最后的课程,但似乎不行.
如果我必须替换在这种情况下使用Spock测试框架的优势是什么?也许我应该删除它并且只与Mockito呆在一起?
解决方法:
我不使用Kotlin,但我之前使用过PowerMock来模拟最终的类/方法和静态方法.我想知道是否有可能使用Spock的GroovyMock和全局GroovySpy功能,并使用Spock 1.1-groovy-2.4对Java代码进行测试.在第一个快速&脏测试场景似乎工作:
正在测试的Java类:
package de.scrum_master.stackoverflow;
public final class FinalClass {
public static final String finalStaticMethod() {
return "x";
}
public final String finalMethod() {
return "x";
}
}
Spock测试:
package de.scrum_master.stackoverflow
import spock.lang.Specification
/**
* See https://stackoverflow.com/q/48391716/1082681
* See http://spockframework.org/spock/docs/1.1/all_in_one.html#GroovyMocks
*/
class FinalClassTest extends Specification {
def "use GroovyMock for final method in final class"() {
given:
FinalClass finalClass = GroovyMock() {
finalMethod() >> "mocked"
}
expect:
finalClass.finalMethod() == "mocked"
}
def "use global GroovySpy for final static method in final class"() {
given:
GroovySpy(FinalClass, global: true)
FinalClass.finalStaticMethod() >> "mocked"
expect:
FinalClass.finalStaticMethod() == "mocked"
}
}
对我来说,两个特征方法在运行测试时都是绿色的.也许你想尝试一下我的例子,然后你的Kotlin课程 – 但不能保证后者不受我的影响.
注意:Spock manual说:
When called from Java code, Groovy mocks will behave like regular mocks.
因此,在将Groovy Mocks作为依赖项注入测试中的Java类时,您可能会感到失望.
更新:好的,我使用那些花哨的GroovyMocks测试了另一个Java类 – 如上所述 – 它不起作用:
使用模拟类作为依赖项的Java类:
package de.scrum_master.stackoverflow;
public class AnotherClass {
public String doSomething(FinalClass finalClass) {
return finalClass.finalMethod();
}
public String doSomethingElse() {
return FinalClass.finalStaticMethod();
}
}
Spock测试:
package de.scrum_master.stackoverflow
import spock.lang.Specification
/**
* See https://stackoverflow.com/q/48391716/1082681
* See http://spockframework.org/spock/docs/1.1/all_in_one.html#GroovyMocks
*/
class AnotherClassTest extends Specification {
def "indirectly use GroovyMock for final method in final class"() {
given:
FinalClass finalClass = GroovyMock() {
finalMethod() >> "mocked"
}
expect:
new AnotherClass().doSomething(finalClass) == "mocked"
}
def "indirectly use global GroovySpy for final static method in final class"() {
given:
GroovySpy(FinalClass, global: true)
FinalClass.finalStaticMethod() >> "mocked"
expect:
new AnotherClass().doSomethingElse() == "mocked"
}
}
不幸的是,两个测试都失败了,因为当从Java类使用时,这些方法不会被截断.即你被PowerMock或Mockito困住了.但是你仍然可以使用所有其他不错的Spock功能,例如数据表,@ Unroll等等.
更新2:解决方案
将其添加到您的Maven构建中(如果您使用Gradle,请执行类似操作):
<dependency>
<groupId>de.jodamob.kotlin</groupId>
<artifactId>kotlin-runner-spock</artifactId>
<version>0.3.1</version>
<scope>test</scope>
</dependency>
现在,您可以将项目kotlin-testrunner中的SpotlinTestRunner与注释结合使用
> @OpenedClasses([Foo,Bar,Zot])
> @OpenedPackages([“de.scrum_master.stackoverflow”,“my.other.package”])
当然这对静态方法不起作用(你仍需要PowerMock),但你的问题是关于闭合Kotlin类中的非静态方法.有了这个测试运行器,你可以模拟它们,因为一个特殊的类加载器在测试执行之前通过Javassist打开它们:
package de.scrum_master.stackoverflow
import de.jodamob.kotlin.testrunner.OpenedClasses
import de.jodamob.kotlin.testrunner.OpenedPackages
import de.jodamob.kotlin.testrunner.SpotlinTestRunner
import org.junit.runner.RunWith
import spock.lang.Specification
/**
* See https://stackoverflow.com/q/48391716/1082681
* See https://github.com/dpreussler/kotlin-testrunner
*/
@RunWith(SpotlinTestRunner)
@OpenedClasses(FinalClass)
//@OpenedPackages("de.scrum_master.stackoverflow")
class AnotherClassSpotlinRunnerTest extends Specification {
def "use SpotlinRunner to stub final method in final class"() {
given:
FinalClass finalClass = Stub() {
finalMethod() >> "mocked"
}
expect:
new AnotherClass().doSomething(finalClass) == "mocked"
}
}
标签:java,unit-testing,testing,mockito,spock 来源: https://codeday.me/bug/20190622/1263185.html