我遇到spock不允许在规范之外创建Mocks的问题 - How to create Spock mocks outside of a specification class?
这似乎仍然很突出,所以我要问的是,给我一个复杂且嵌套的DI图是什么才是最有效的方式来注入'图中深处的模拟表示?
理想情况下,我为正常部署设置了一个bean定义,在运行单元测试时有另一个bean定义设置,这个定义设置为适用的Mocks
e.g。
@Configuration
@Profile("deployment")
public class MyBeansForDeployment {
@Bean
public MyInterface myBean() {
return new MyConcreateImplmentation();
}
}
&安培;&安培;
@Configuration
@Profile("test")
public class MyBeansForUnitTests {
@Bean
public MyInterface myBean() {
return new MyMockImplementation();
}
}
答案 0 :(得分:1)
你可以尝试实现一个BeanPostProcessor,它将用测试双精度替换你想要的bean,如下所示:
public class TestDoubleInjector implements BeanPostProcessor {
...
private static Map<String, Object[]> testDoubleBeanReplacements = new HashMap<>();
public void replaceBeanWithTestDouble(String beanName, Object testDouble, Class testDoubleType) {
testDoubleBeanReplacements.put(beanName, new Object[]{testDouble, testDoubleType});
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (testDoubleBeanReplacements.containsKey(beanName)) {
return testDoubleBeanReplacements.get(beanName)[TEST_DOUBLE_OBJ];
}
return bean;
}
在测试中,在初始化应用程序上下文之前设置如下所示的模拟。确保将TestDoubleInjector作为bean包含在测试上下文中。
TestDoubleInjector testDoubleInjector = new TestDoubleInjector()
testDoubleInjector.replaceBeanWithTestDouble('beanToReplace', mock(MyBean.class), MyBean.class)
答案 1 :(得分:1)
从Spock 1.1开始,您可以在规范类之外创建模拟(分离的模拟)。其中一个选项是DetachedMockFactory
。请查看the documentation或my answer to the question you linked。
答案 2 :(得分:-1)
@WebAppConfiguration
@SpringApplicationConfiguration(TestApp)
@IntegrationTest('server.port:0')
class HelloSpec extends Specification {
@Autowired
@Qualifier('swappableHelloService')
HotSwappableTargetSource swappableHelloService
def "test mocked"() {
given: 'hello service is mocked'
def mockedHelloService = Mock(HelloService)
and:
swappableHelloService.swap(mockedHelloService)
when:
//hit endpoint
then:
//asserts
and: 'check interactions'
interaction {
1 * mockedHelloService.hello(postfix) >> { ""Mocked, $postfix"" as String }
}
where:
postfix | _
randomAlphabetic(10) | _
}
}
这是TestApp(覆盖你想用代理模拟的bean)
class TestApp extends App {
//override hello service bean
@Bean(name = HelloService.HELLO_SERVICE_BEAN_NAME)
public ProxyFactoryBean helloService(@Qualifier("swappableHelloService") HotSwappableTargetSource targetSource) {
def proxyFactoryBean = new ProxyFactoryBean()
proxyFactoryBean.setTargetSource(targetSource)
proxyFactoryBean
}
@Bean
public HotSwappableTargetSource swappableHelloService() {
new HotSwappableTargetSource(new HelloService());
}
}