java - Spring配置的模拟给出了两个不同的实例

标签 java spring testing easymock

注意:我特意从类和对象的名称中删除了单词,所以请原谅我的代码示例中的可怕名称

我有一个测试类,它使用一些测试 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/

相关文章:

java - Java 中的 FileLock 在同一进程内或不同进程之间或两者之间跨多个线程是否安全?

java - 如何使用java计算gradian中的sin

spring - <task :annotation-driven> in spring 4. 3 的注释是什么

java - 如何使用 JPA/Hibernate 延迟实例化属性?

reactjs - 减小 Cypress docker 镜像大小

javascript - 如何在 Sinon 中 stub 匿名函数?

java - 为什么catalina.home_IS_UNDEFINED目录是Logback在同一个项目目录下生成的?

java - 我可以在普通 Java 应用程序中使用 gwt GUI 吗?

java - 如何在 spring-web servlet 中接受文本/csv 作为内容类型?

reactjs - 如何模拟 React setState 进行 API 测试