3

我有一个这样的 JUnit 测试类:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration( locations = { "beanDefinitions.xml"})
public class MyTest {

    @Mocked private SomeDependency usedInSpringContext;

    @Test public void letsTest() {
        ...
    }
}

问题是,Spring runner 在 JMockit 有机会模拟它们之前加载它的 bean。如何避免?这是 JMockit 1.0 和 Spring 3.07。我宁愿让我的 beanDefinitions.xml 保持不变。

被测代码是遗留代码。它包含许多我无法轻易摆脱的硬编码弹簧依赖项。因此第一步 - 嘲笑。

4

2 回答 2

2

您可以使用自定义 FactoryBean。

此博客对此进行了解释。这是示例代码

它使用 easymock 或 Mockito。但我相信您可以轻松地将其移植到 JMockit。

编辑:我忽略了你不希望你的 beanDefinitions.xml 被修改。但我的建议包括修改。

于 2013-02-05T18:39:15.083 回答
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 文件,那么您正在编写集成测试,而不是单元测试。

于 2013-02-05T23:20:28.540 回答