每次集成测试后,Spring上下文变脏

时间:2013-05-30 09:54:59

标签: java spring testing dependencies integration

我最近在我目前的项目中担任自由职业者。我投入的一件事就是失败的詹金斯建筑(从4月8日开始失败,在我开始前一周)。

一般来说,您可以在日志中看到一系列DI问题。我做的第一件事就是从相同的应用程序上下文开始,以相同的方式使所有测试工作。 他们还实施了自己的“嘲弄”的东西,似乎无法正常工作。在与开发者讨论后,我建议开始使用Springockito。 (对于某个模块,他们需要模拟他们的集成测试 - 遗留原因,这是无法改变的)

无论如何,事情之后开始失败了。在测试中被嘲笑的很多豆子都没有被嘲笑,或者没有找到或者其他什么。通常,它会在加载应用程序上下文时失败,说明缺少一个或另一个bean。

我尝试了不同的东西和不同的方法,但最后,只有我最担心的事情才能起作用:将@DirtiesContext添加到每个测试中。现在,maven构建开始再次变为绿色,测试开始做他们应该做的事情。但是我每次都在重新加载Spring上下文,这需要时间 - 这都是相对的,因为上下文加载大约1-2秒。

这个故事的旁注是他们已经升级到Hibernate 4,因此升级到Spring 3.2。以前,他们使用的是旧版本的Spring 3.当时所有测试都在进行,并且没有必要使用@DirtiesContext。

现在,让我最担心的是,我无法立即想到对这种奇怪行为的解释。通过启动使用@Autowired bean的测试,几乎可以看出Springs上下文变脏了。并非所有测试都使用Mocks,因此不可能。 这听起来对任何人都很熟悉吗?有没有人与Spring(最新版本)的集成测试有相同的经验?

在Stackoverflow上,我找到了这张票:How can a test 'dirty' a spring application context? 它似乎几乎总结了我所看到的行为,但重点是我们是自动装配服务/存储库/ ......,而且我们在这些类中没有任何设置器。

有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:4)

要回答我自己的问题,秘密就在Spring版本中。我们使用的是Spring 3.1.3,而我推测他们使用的是Spring 3.2(他们一直在谈论Spring版本的最新升级)。

这里有一个解释,一篇博文,我在寻找修复时偶然发现:http://blog.springsource.org/2012/11/07/spring-framework-3-2-rc1-new-testing-features/

相关文章的复制粘贴:

  

在Spring配置中使用通用工厂方法并不特定于>测试,但通常使用通用工厂方法(如EasyMock.createMock(MyService.class)或Mockito.mock(MyService.class))来创建在>测试应用程序上下文中对Spring bean进行动态模拟。例如,在Spring Framework 3.2之前,以下>配置可能无法将OrderRepository自动装配到OrderService中。原因是>根据应用程序上下文中bean的初始化顺序,> Spring可能会将orderRepository bean的类型推断为java.lang.Object>而不是com.example.repository。 OrderRepository。

那么,我是如何解决这个问题的呢?好吧,我做了以下步骤:

  • 创建一个新的maven模块
  • 过滤掉需要模拟的测试。所有非模拟测试都将在Spring构建中运行,在单独的Failsafe运行中运行(我创建了一个基础包“clean”,并将它们整理出来)
  • 将所有模拟测试放在名为“mocked”的基础包中,并在Failsafe中为模拟测试进行额外运行。
  • 每个模拟测试都使用Springockito来创建模拟。我也使用Springockito注释,轻松地在一个@ReplaceWithMock上做。然后使用@DirtiesContext对每个模拟测试进行注释,因此每次测试后上下文都会变脏,并且每次测试都会重新引入Spring上下文。

我能给出的唯一合理的解释是,上下文实际上是脏的,因为有一个框架(Springockito)从Spring框架接管Spring bean的管理。我不知道这是否正确,但这是我能想到的最好的解释。事实上,这是脏上下文的定义,这就是我们需要将其标记为脏的原因。

使用此策略,我获得了构建并再次运行,并且所有测试都运行正常。它并不完美,但它有效,并且它是一致的。