注意:我特意从类和对象的名称中删除了单词,所以请原谅我的代码示例中的可怕名称
我有一个测试类,它使用一些测试 Spring 上下文文件来设置我的应用程序。该应用程序是 Web 服务的包装器。
因为这是一个测试,所以我模拟了相关 Web 服务的主要接口(interface)(ITransporter
类)。这使我能够设置预期,以便我可以检查发送到 Web 服务的请求是否: 采用预期的格式;完成预期的字段;等等……
我的 mock 在一个名为 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>
这个上下文文件用在两个地方。 (我担心这就是我的问题所在。)
首先是测试类,定义如下:
@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
接口(interface)的单例测试实现? (基本上是创建一个行为与我的模拟现在完全一样的 stub 。)
编辑:(答案)
正如 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" />
最佳答案
哦,是的,这是一个问题。当您创建一个新的上下文时,就像为 Spring 创建一个新的对象空间一样。在您的 XML 文件中创建的与在您的手工环境中创建的不同。它们总是会产生不同的变量。
我以前曾被那个问题激怒过。
如果您想要相同的单例,您唯一的希望就是管理您自己的单例。
关于java - Spring配置的模拟给出了两个不同的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21627263/