Spock 如何在方法中模拟 Autowired class' 函数调用
Spock How to mock Autowired class' function call within a method
我有一个 class 我想测试它看起来像这样:
包裹 com.something;
import org.springframework.beans.factory.annotation.Autowired;
public class ClassToTest implements InterfaceToTest{
@Autowired
AnotherService serviceA;
@Override
public List<String> methodToTest(List<String> randomVar){
...
String stringA = serviceA.someFunction(randomVar);
...
}
}
在使用 spock 进行测试时,如何将调用 serviceA.someFunction(randomVar) 的结果模拟为 return 我选择的任何字符串?
package com.something;
import spock.lang.Shared
import spock.lang.Specification
class TestClass extends Specification{
@Shared InterfaceToTest classToTest = new ClassToTest()
static doWithSpring = {
serviceA(AnotherService)
}
def "tests-part-1"(){
when: "something"
...
then: "expect this"
...
}
}
我不知道从这里到哪里去。我的 IDE 显示我添加到测试 class 的 doWithSpring 代码有错误。关于如何处理这个问题有什么想法吗?
我建议更多地从单元测试的角度来考虑它。你想模拟 spring 框架的东西,只是确保你正在测试你的逻辑。这对 Spock 来说很容易做到。
ClassToTest myClass = new ClassToTest(serviceA: Mock(AnotherService))
def "test my method"() {
when:
myClass.methodToTest([])
then:
1 * myClass.serviceA.someFunction([]) >> 'A string'
}
从这里,您可以查看驱动它的数据或使用 >>> 并将您想要的不同字符串列表传递给 return。
如果您正在进行单元测试,请按照@rockympls 的建议进行操作。
如果您正在 integration/component 测试,则包含 spock-spring
依赖项并查看来自 Spock 人员的 test examples。此外,如果您使用 Spring Boot 1.4+,您可以执行以下操作:
@SpringBootTest(classes = Application)
@ContextConfiguration
class SomeIntegrationTest extends Specification {
@Autowired
SomeService someService
def 'some test case'() {
...
}
}
有关 Spring 引导测试内容的更多信息,请参阅 this。
启用单元测试的一个简单解决方案是更改 ClassToTest 以具有一个构造函数来设置 serviceA 字段,如下所示:
import org.springframework.beans.factory.annotation.Autowired;
public class ClassToTest implements InterfaceToTest{
private AnotherService serviceA;
@Autowired
public ClassToTest(final AnotherService serviceA){
this.serviceA = serviceA;
}
@Override
public List<String> methodToTest(List<String> randomVar){
...
String stringA = serviceA.someFunction(randomVar);
...
}
}
然后在您的 spock 单元测试中,您可以在构造函数中提供一个模拟:
class TestClass extends Specification{
def mockServiceA = Mock(AnotherService)
@Shared InterfaceToTest classToTest = new ClassToTest(mockServiceA)
并且在每个测试用例中,您可以使用通常的 spock 方式进行模拟:
1 * mockServiceA.someFunction(_) >> 'A string'
我有一个 class 我想测试它看起来像这样: 包裹 com.something;
import org.springframework.beans.factory.annotation.Autowired;
public class ClassToTest implements InterfaceToTest{
@Autowired
AnotherService serviceA;
@Override
public List<String> methodToTest(List<String> randomVar){
...
String stringA = serviceA.someFunction(randomVar);
...
}
}
在使用 spock 进行测试时,如何将调用 serviceA.someFunction(randomVar) 的结果模拟为 return 我选择的任何字符串?
package com.something;
import spock.lang.Shared
import spock.lang.Specification
class TestClass extends Specification{
@Shared InterfaceToTest classToTest = new ClassToTest()
static doWithSpring = {
serviceA(AnotherService)
}
def "tests-part-1"(){
when: "something"
...
then: "expect this"
...
}
}
我不知道从这里到哪里去。我的 IDE 显示我添加到测试 class 的 doWithSpring 代码有错误。关于如何处理这个问题有什么想法吗?
我建议更多地从单元测试的角度来考虑它。你想模拟 spring 框架的东西,只是确保你正在测试你的逻辑。这对 Spock 来说很容易做到。
ClassToTest myClass = new ClassToTest(serviceA: Mock(AnotherService))
def "test my method"() {
when:
myClass.methodToTest([])
then:
1 * myClass.serviceA.someFunction([]) >> 'A string'
}
从这里,您可以查看驱动它的数据或使用 >>> 并将您想要的不同字符串列表传递给 return。
如果您正在进行单元测试,请按照@rockympls 的建议进行操作。
如果您正在 integration/component 测试,则包含 spock-spring
依赖项并查看来自 Spock 人员的 test examples。此外,如果您使用 Spring Boot 1.4+,您可以执行以下操作:
@SpringBootTest(classes = Application)
@ContextConfiguration
class SomeIntegrationTest extends Specification {
@Autowired
SomeService someService
def 'some test case'() {
...
}
}
有关 Spring 引导测试内容的更多信息,请参阅 this。
启用单元测试的一个简单解决方案是更改 ClassToTest 以具有一个构造函数来设置 serviceA 字段,如下所示:
import org.springframework.beans.factory.annotation.Autowired;
public class ClassToTest implements InterfaceToTest{
private AnotherService serviceA;
@Autowired
public ClassToTest(final AnotherService serviceA){
this.serviceA = serviceA;
}
@Override
public List<String> methodToTest(List<String> randomVar){
...
String stringA = serviceA.someFunction(randomVar);
...
}
}
然后在您的 spock 单元测试中,您可以在构造函数中提供一个模拟:
class TestClass extends Specification{
def mockServiceA = Mock(AnotherService)
@Shared InterfaceToTest classToTest = new ClassToTest(mockServiceA)
并且在每个测试用例中,您可以使用通常的 spock 方式进行模拟:
1 * mockServiceA.someFunction(_) >> 'A string'