spring 被描述为测试友好的原因之一是因为它可能很容易在单元测试中只添加新的或模拟的东西。
或者,我们已经成功地使用了以下设置,我认为它非常接近您想要的,我强烈推荐它:
对于在不同上下文中需要不同实现的所有 bean,请切换到基于注释的布线。你可以让其他人保持原样。
实现以下一组注解
<context:component-scan base-package="com.foobar">
<context:include-filter type="annotation" expression="com.foobar.annotations.StubRepository"/>
<context:include-filter type="annotation" expression="com.foobar.annotations.TestScopedComponent"/>
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>
然后,您使用@Repository 注释您的实时实现,使用@StubRepository 注释您的存根实现,任何应该仅使用@TestScopedComponent 出现在单元测试夹具中的代码。您可能会遇到需要更多注释的情况,但这是一个很好的开始。
如果你有很多 spring.xml,你可能需要创建一些新的 spring xml 文件,这些文件基本上只包含组件扫描定义。您通常只需将这些文件附加到您的常规 @ContextConfiguration 列表中。这样做的原因是因为您经常以不同的上下文扫描配置结束(相信我,如果您正在进行网络测试,您将至少再添加 1 个注释,这会产生 4 个相关组合)
然后你基本上使用
@ContextConfiguration(locations = { "classpath:/path/to/root-config.xml" })
@RunWith(SpringJUnit4ClassRunner.class)
请注意,此设置不允许您交替组合存根/实时数据。我们试过这个,我认为这会导致一团糟,我不推荐任何人;)我们要么连接全套存根,要么提供全套实时服务。
在依赖关系通常非常大的东西附近测试 gui 时,我们主要使用自动连接的存根依赖关系。在更干净的代码区域,我们使用更常规的单元测试。
在我们的系统中,我们有以下用于组件扫描的 xml 文件:
- 用于常规网络制作
- 仅用于使用存根启动 web
- 用于集成测试(在junit中)
- 用于单元测试(在junit中)
- 用于 selenium web 测试(在 junit 中)
这意味着我们总共有 5 种不同的系统范围配置,我们可以使用它们来启动应用程序。因为我们只使用注解,所以即使是我们想要连接的单元测试,spring 也足够快地自动连接。我知道这是非传统的,但它真的很棒。
Out 集成测试使用完整的实时设置运行,有一次或两次我决定变得非常务实,并希望拥有 5 个实时布线和一个模拟:
public class HybridTest {
@Autowired
MyTestSubject myTestSubject;
@Test
public void testWith5LiveServicesAndOneMock(){
MyServiceLive service = myTestSubject.getMyService();
try {
MyService mock = EasyMock.create(...)
myTestSubject.setMyService( mock);
.. do funky test with lots of live but one mock object
} finally {
myTestSubject.setMyService( service);
}
}
}
我知道测试纯粹主义者会为此而全力以赴。但有时它只是一个非常实用的解决方案,当替代方案真的很丑陋时,它会变得非常优雅。同样,它通常在那些 gui 附近的地区。