如何重新初始化我的bean

时间:2010-12-06 22:00:03

标签: java unit-testing spring-mvc dependency-injection mockito

我的applicationContext-test.xml中有一个bean,用于模拟外部搜索引擎。这样,当我运行测试时,只要我的应用程序代码引用此搜索引擎,我就知道我使用的是我的模拟引擎而不是真正的引擎。

我面临的一个问题是我希望这个引擎在不同的场景中表现不同。例如,当我调用getDocuments()时,我通常希望它返回文档。但有时我希望它抛出异常以确保我的应用程序代码正确处理异常。

我可以通过在我的测试代码中引用bean并更改一些存根来实现这一点,但是我必须将存根更改回原来的状态,这样我的其他测试也会通过。由于种种原因,这似乎是不好的做法,所以我正在寻找替代方案。

我考虑的一个替代方案是完全重新初始化bean。使用静态工厂方法从applicationContext-test.xml初始化bean。我想做的是:

  1. 从我的测试代码中引用bean来更改它的一些存根
  2. 使用这些新存根运行测试
  3. 在此测试结束时,使用applicationContext-test.xml中指定的静态工厂方法重新初始化bean
  4. 我试过这样的事情:

        ClassPathXmlApplicationContext appContext = new ClassPathXmlApplicationContext(
                new String[] { "applicationContext-test.xml" });
        Factory factory = appContext.getBean(Factory.class);
        factory = EngineMocks.createMockEngineFactory();
    

    但这不是诀窍。在此之后运行的任何测试仍将失败。似乎我的新factory变量包含我想要的Factory并且相应地表现,但是当bean被引用到其他地方时,getDocuments()仍会抛出之前存根的异常。显然,我的重新初始化只影响局部变量,而不影响bean本身。

    有人可以告诉我如何实现目标吗?

    更新

    虽然我很欣赏有关如何编写更好的测试和更好的模拟的建议,但我的目标是重新初始化bean。我相信学习如何做到这一点是否适合我的用例是有价值的(我相信它确实适合我的用例,但我很难说服我的一些批评者)。

    唯一可以得到我的投票或绿色滴答答案的答案是建议我如何重新初始化我的bean。

3 个答案:

答案 0 :(得分:1)

您应该在需要结果时定义案例,并在需要例外时定义案例。它们应该通过方法的输入参数来区分。否则它不是一个好的测试。因此,对于给定的参数集,输出应该是可预测的。

答案 1 :(得分:0)

如何注入搜索引擎的不同实现?只需创建更多代表搜索引擎不同模拟的bean。

  • 一个测试类用一个mock初始化,另一个测试类用另一个mock初始化;当然,这意味着你将为你正在测试的某个类提供更多的测试类(不是那么好/干净)

...或

  • 在1个测试类中注入(搜索引擎的)更多模拟。一些测试方法(来自该测试类)使用一个模拟,其他测试方法使用另一个模拟

答案 2 :(得分:0)

而不是:

factory = EngineMocks.createMockEngineFactory();

做的:

factory.callMethodThatChangesTheStateOfThisObjectSuchThatItIsSuitableForYourTest(withOptionalParameters);

此外,如果您正在使用Spring Integration Testing,请确保使用@DirtiesContext注释您的方法,这样它不会影响下一个测试。