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

时间:2012-03-01 16:58:30

标签: spring spring-mvc spring-3

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

2 个答案:

答案 0 :(得分: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文档的this section

有几种方法可以在生产中设置活动配置文件,但我之前使用的方法是在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>

答案 1 :(得分: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”做这种事情的方法。但它非常简单易行。