注意:我故意从类和对象的名称中删除了单词,所以请原谅我的代码示例中的可怕名称
我有一个测试类,它使用一些测试Spring上下文文件来设置我的应用程序。该应用程序是Web服务的包装器。
由于这是一个测试,我已经模拟了有问题的Web服务的主界面(ITransporter
类)。这使我能够设置期望,以便我可以检查发送到Web服务的请求是否:以预期的格式;有预期的字段完成;等...
我的模拟在名为test-beans-context.xml
的文件中定义,并传递到一些服务bean,如下所示:
<bean id="mockTransporter" class="org.easymock.EasyMock" factory-method="createMock" scope="singleton">
<constructor-arg index="0" value="transport.ITransporter" />
</bean>
<bean id="accountService" class="service.AccountService">
<property name="transporter" ref="mockTransporter" />
</bean>
此上下文文件用于2个地方。 (我担心这是我的问题所在。)
第一个是测试类,定义如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( locations={"classpath:test-beans-context.xml"} )
public class AbstractIntegrationTest {
@Autowired
private ITransporter mockTransporter;
//Some tests that perform expectations like the following:
// EasyMock.reset( this.mockTransporter );
// EasyMock.expect( this.mockTransporter.sendRequest( EasyMock.capture(this.requestXmlCapture) ) ).andReturn( responseXml );
}
第二个位置是在用于发送请求的逻辑路径中的类中。它加载一个单独的XML上下文文件/lite-api-context.xml
,然后在我的测试设置中导入测试文件。
public class Factory implements IFactory {
public Factory() {
context = new ClassPathXmlApplicationContext("/lite-api-context.xml");
}
@Override
public IAccountService getAccountService() {
return (IAccountService) context.getBean("accountService");
}
}
lite-api-context.xml
包括:
<import resource="classpath:/test-beans-context.xml" />
我的问题是,在测试类中,我得到了一个不同的模拟ITransporter
实例,最终被我的其他服务使用。因此,我设置的期望从未实际执行,因为模拟最终会成为不同的实例。
有没有办法确保我在两个地方都获得相同的实例?
或者我是否必须创建自己的ITransporter
接口的单例测试实现? (基本上创建一个与我的模拟行为完全相同的存根。)
编辑:(答案)
正如Thom所说,似乎我需要创建自己的类来管理模拟。
我想在这里添加我的解决方案,以防任何人遇到类似的问题。
刚刚写了一个像这样的快速静态类:
public class MockTransporter {
private static ITransporter mockTransporter = EasyMock.createMock(ITransporter.class);
public static final ITransporter getInstance() {
return mockTransporter;
}
}
并且必须将XML配置更改为:
<bean id="mockTransporter" class="MockTransporter" factory-method="getInstance" />
答案 0 :(得分:1)
我之前已被烧过。
你只希望如果你想要同样的人来管理自己的单身人士。
答案 1 :(得分:1)
解决此问题的理想方法是将Factory创建为Spring bean,并将AccountService注入Factory bean。 通常,在生产代码中应避免使用context.getBean(),因为它会损害控制反转的概念(有关更多信息,请参阅:Why is Spring's ApplicationContext.getBean considered bad?)。可以在测试代码中使用它。