在一个上下文中用另一个上下文的模拟版本替换Spring Bean

12

我正在编写一个集成测试,在启动过程中初始化应用程序上下文xml。 测试类中有几个测试方法,这些方法使用特定的Bean“X”(已在xml中定义)。 我的实际要求是仅为其中一个测试方法模拟bean X。

在测试方法内部:我尝试使用ClassPathXMLApplicationContext创建了一个单独的应用程序上下文,其中仅包含模拟bean'M'。

现在我有两个应用程序上下文(AC): 1. 在测试用例启动期间创建的一个(其中包含实际bean X) 2. 在测试方法中使用ClassPathXMLApplicationContext创建的另一个(其中包含模拟bean M)。

我想替换AC:1中的实际bean定义“X”,使用AC:2中的模拟bean定义“M”。

可以有人请帮忙解答吗?

3个回答

23
你可以:
  • 如果你使用的是Spring 3.1,可以使用@Profile注解。
  • 可以使用@Primary注解。
  • 使用qualifiers
  • 在Spring上下文中手动绑定bean。
我相信还有更多选项。

2
@Primary是最佳答案:“表示当有多个候选项符合自动装配条件时,应该优先选择一个bean…” - jsosnowski
对我来说,@Primary也是最好的答案,但当使用@Qualifier时会发生什么? - deFreitas
真的很喜欢@Primary建议。这在特殊测试场景中非常有帮助... - Martin

17

除非您关闭并再次刷新ApplicationContext,否则没有明确的方法可以替换刷新后的bean。

要模拟它,常见的方法是使用要替换的bean的Proxy,并在运行时更改目标。

您可以使用框架aop支持类轻松完成此操作:

<bean id="realBean" class="RealClass" />
<bean id="mockBean" class="MockClass" />
<bean id="targetSource" class="org.springframework.aop.target.HotSwappableTargetSource">
    <constructor-arg ref="realBean" />
</bean>

<bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="targetSource" ref="targetSource" />
</bean>

 

@Test
public void testWithMockBean() {
Object real = targetSource.swap(mock);
....
// do your test work
...
targetSource.swap(real);

}

我在一个小例子中尝试了这个。要点在这里:https://gist.github.com/harschware/111416de4c8fe53689b8c5ca15140a67 - harschware

3
创建一个 testApplicationContext:
<beans>
    <import resource="classpath*:appContext.xml" />
    <bean id="mockbeanOfX" class=....../>
</beans>

然后在测试用例中加载这个测试应用程序上下文。现在,您可以从应用程序上下文中获取模拟bean,并在需要的地方传递它。


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