2014-04-03 85 views
3

我被擊中的問題是斯波克不允許嘲弄的規範之外創建 - How to create Spock mocks outside of a specification class?測試的模擬豆春與斯波克

這似乎仍然懸而未決所以要問的是,給我有一個複雜和嵌套的DI圖什麼是在圖中深入「模擬」表示的最有效方式?

理想情況下,我有一個bean定義爲正常部署設置和另一個運行時,單元測試,它是該定義集作爲適用嘲笑

例如

@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(); 
    } 

} 

回答

1

你可以嘗試實現了BeanPostProcessor將替換您要使用測試雙打的豆類,如下面所示:

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

它可以使用HotSwappableTargetSource

@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(覆蓋你想代理嘲笑豆)

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()); 
} 
} 

看一看這個例子https://github.com/sf-git/spock-spring