如何覆盖应用程序上下文中定义的单个bean

6

我有一个访问外部web服务的Web应用程序。 我正在为Web应用程序编写自动化验收测试套件。 由于外部Web服务开销巨大,我不想调用它,而是想模拟这个Web服务。 如何在不改变Web应用程序的应用上下文的情况下实现这一点? 我们最近迁移到了Spring 3.1,因此我倾向于使用新的环境功能。 这些新功能是否可以帮助我覆盖单个Web服务并保留应用程序上下文?

2个回答

9
我会使用Spring的@Profile功能,我猜这就是你提到的“环境特性”。
例如:
@Service @Profile("dev")
public class FakeWebService implements WebService {
}

@Service @Profile("production")
public class ExternalWebService implements WebService {
}

编辑

要在您的测试中指定使用哪个配置文件:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/app-config.xml")
@ActiveProfiles("dev")
public class MyAcceptanceTest {
}

请参见Spring文档中的这一部分获取更多详细信息。
在生产环境中,有几种设置活动配置文件的方法,但我曾经使用的方法是在web.xml文件中:
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>production</param-value>
    </init-param>
</servlet>

在测试配置(或生产配置)中,您在哪里指定使用哪个“Profile”? - nicholas.hauschild
我已经更新了我的答案,并提供了一些示例。如果需要的话,您也可以在beans.xml中使用配置文件设置。 - seanhodges

4
我会使用一个BeanFactoryPostProcessor来实现这个功能,该处理器仅在需要模拟的测试场景中注册。 BeanFactoryPostProcessor允许您在应用程序上下文被创建和填充后立即修改它。您可以寻找特定bean的名称,并为其注册另一个bean。
public class SystemTestBeanFactoryPostProcessor implements BeanFactoryPostProcessor
{
    @Override
    public void postProcessBeanFactory(final ConfigurableListableBeanFactory factory) throws BeansException
    {
        final MyInterface myInterface = new MyInterfaceStub();
        factory.registerSingleton("myInterfaceBeanName", myInterface);
    }
}

这将允许您仅覆盖您想要存根/模拟的bean。

我不确定这是否是实现此类操作的“最新3.x”方式。但它非常简单直接,易于实施。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接