我有一个像这样的JUnit测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( locations = { "beanDefinitions.xml"})
public class MyTest {
@Mocked private SomeDependency usedInSpringContext;
@Test public void letsTest() {
...
}
}
问题是,Spring运行器在JMockit有机会模仿它们之前加载它的bean。怎么避免呢?这是JMockit 1.0和Spring 3.07。我宁愿让beanDefinitions.xml保持不变。
正在测试的代码是遗留的。它包含许多硬编码的spring依赖项,我无法轻易摆脱它。因此第一步 - 嘲笑。
答案 0 :(得分:2)
您可以使用自定义FactoryBean。
它使用easymock或Mockito。但我相信你可以很容易地将它移植到JMockit。
编辑:我忽略了您不希望修改beanDefinitions.xml。但我的建议包括修改。答案 1 :(得分:0)
关于Spring的一个很棒的事情,以及一般的依赖注入,就是你的类不会因代码满足它们的依赖性而变得杂乱无章。他们只是坐着等待其他人填写合作对象。所以插入模拟对象应该是微不足道的。
// no Spring runner or context configuration
public class FooTest {
Foo foo;
@Before
public void setup() {
foo = new Foo();
foo.setDependency(mock(dependency)); // details depend on mocking framework
}
}
使用这种方法,您不会自动装配或以其他方式注入您正在测试的对象,至少如果您打算通过将其指向模拟协作者来重新配置它,则至少不会。如果被测代码有很多依赖关系,你可以使用大量的设置代码,但这是正常的。
不可否认,有些东西(比如数据库)很难模拟,所以你需要一种不同的测试方法来验证你的SQL查询(例如)是否符合你的意思。这开始于一个单独的bean定义文件,其中包含:
<jdbc:embeded-database id="datasource"/>
有关详细信息,请参阅http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/testing.html。
棘手的部分是,如果你一直没有编写Junit测试,你可能已经陷入了每个bean似乎都依赖于其他所有bean的情况。所以你试图测试的“单元”不是一个类,而是一堆相互关联的类。在这种情况下,我建议将bean定义文件分成更小的部分,然后为每个部分编写单元测试。
使用这种方法,您可以让Spring连接正在测试的代码,因为Spring配置是该单元的一部分。单元测试代码仍然模拟并插入该单元外部的依赖项。
如果您坚持完全使用真正的beanDefinitions.xml文件,那么您正在编写集成测试,而不是单元测试。