7

我最近开始作为我当前项目的自由职业者。我投入的一件事是失败的 Jenkins 构建(它从 4 月 8 日开始失败,在我开始这里的一周前)。

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

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

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

这个故事的一个侧面说明是他们已经升级到 Hibernate 4,因此升级到 Spring 3.2。以前,他们使用的是旧版本的 Spring 3。当时所有的测试都可以正常工作,并且不需要 @DirtiesContext 的东西。

现在,最让我担心的是,我无法立即想到对这种奇怪行为的解释。几乎似乎 Springs 上下文被弄脏了,只需启动一个使用 @Autowired bean 的测试。并非所有测试都使用 Mocks,所以不可能这样。这听起来很熟悉吗?有没有人在使用(最新版本的)Spring 进行集成测试时有相同的经验?

在 Stackoverflow 上,我发现了这张票:测试如何“弄脏”spring 应用程序上下文? 它似乎几乎总结了我所看到的行为,但关键是我们正在自动装配服务/存储库/......,并且我们在这些类上没有任何设置器。

有什么想法吗?

谢谢!

4

1 回答 1

5

为了回答我自己的问题,秘密就在 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 创建动态模拟>test 应用程序上下文中的 bean。例如,在 Spring Framework 3.2 之前,以下 >configuration 可能无法将 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 的管理。我不知道这是否正确,但这是我能想到的最好的解释。事实上,这就是脏上下文的定义,这就是我们需要将其标记为脏上下文的原因。

使用这个策略,我得到了构建并再次运行,所有测试都运行正常。它并不完美,但它正在工作,而且是一致的。

于 2013-07-09T18:44:52.743 回答