一个可能有高级答案的简单问题。
问题:
我的问题是,有没有办法在应用程序上下文中仅实例化特定JUnit测试所需的类?
原因:
我的应用程序环境变得越来越大。我也做了很多集成测试,所以你猜我会理解当我说每次运行测试时,我的应用程序上下文中的所有类都会被实例化,这需要时间。
这个例子:
说类Foo只注入吧
public class Foo {
@Inject
Bar bar;
@Test
public void testrunSomeMethod() throws RegisterFault {
bar.runSomeMethod();
}
但是应用程序上下文有bean foobar和bar。我知道这不是一个虚拟应用程序上下文,但请确保我的所有代码都能正常工作。
<beans>
<bean id="foobar" class="some.package.FooBar"/>
<bean id="bar" class="some.package.Bar"/>
<beans>
那么我如何告诉spring只实例化Bar并忽略测试类foo的FooBar。
谢谢。
这不是直接的答案,所以我不会将其标记为解决方案。但希望它有所帮助。
一般来说,我看到三个选项
正如VinayVeluri很好地回答。创建单独的上下文并分别在每个测试中启动它们。
每次测试都创建一次上下文。就像这里一样: 在junit测试类中重用spring应用程序上下文 这是一次性测试所有测试的重大优化。
混合这两个第一点。创建一个较小的上下文仅用于测试目的。嘲笑,什么从未经过测试,但可以抛出NPE等。像这里: 将Mockito模拟注入Spring bean 加强上下文构建。并在第2点重新使用它。一次性构建所有测试。就个人而言,我会选择那个。
这个等待关于某种智能测试运行器的答案,它为每个测试创建最少的所需上下文。
考虑添加 default-lazy-init="true"
到你的spring上下文xml beans标签(或添加 lazy-init="true"
那些需要很长时间才能启动的特定豆类。
这将确保只创建那些使用applicationContext.getBean(class-or-bean-name)调用或通过注入的bean @Autowired
/ @Inject
进入你的测试。 (像其他一些类型的豆类 @Scheduled
但是仍会创建bean,但你需要检查是否存在问题)
(如果使用spring Java配置,请添加 @Lazy
到配置文件)
警告 - 如果有一个bean没有使用applicationContext.getBean()显式初始化,或者被注入为使用applicationContext.getBean()获得的bean所使用的依赖项,则该bean将不再构造或初始化。根据您的应用程序,这可能导致事情失败或不。也许你可以选择性地将这些豆子标记为 lazy-init="false"
是的,我们可以使用每个测试用例的上下文来做到这一点。使用测试用例所需的bean准备测试上下文xml文件。
如果您使用maven,请将test-context.xml放在下面 src/test/resources
夹。
使用以下注释注释所需的测试类
@ContextConfiguration(locations = "classpath:test-application-context.xml")
这有助于仅加载测试用例的特定bean。
如果你有两种测试用例,那么
@Runwith(SpringJUnit4Runner.class)
@ContextConfiguration(locations = "classpath:test-context-case1.xml")
public class TestClassCase1 {}
@Runwith(SpringJUnit4Runner.class)
@ContextConfiguration(locations = "classpath:test-context-case2.xml")
public class TestClassCase2 {}