0

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

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

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

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

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

我试过这样的事情:

    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 的答案。

4

3 回答 3

1

您应该定义需要结果的情况和需要异常的情况。它们应该通过方法的输入参数来区分。否则就不是一个好的测试。因此,对于给定的一组参数,输出应该是可预测的。

于 2010-12-06T22:03:44.477 回答
0

代替:

factory = EngineMocks.createMockEngineFactory();

做:

factory.callMethodThatChangesTheStateOfThisObjectSuchThatItIsSuitableForYourTest(withOptionalParameters);

此外,如果您使用的是 Spring 集成测试,请确保使用 @DirtiesContext 注释您的方法,以免影响下一次测试。

于 2011-03-25T03:15:11.357 回答
0

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

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

或者...

  • 在 1 个测试类中注入更多模拟(搜索引擎的)。一些测试方法(来自该测试类)使用一个模拟,其他测试方法使用另一个模拟
于 2010-12-07T16:10:50.280 回答