每次集成测试后Spring上下文都很脏 [英] Spring context dirty after each integration test

查看:83
本文介绍了每次集成测试后Spring上下文都很脏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近开始是我当前项目的自由职业者。我丢给自己的一件事是詹金斯(Jenkins)建造失败(从4月8日开始,也就是我在这里开始的一周前,它失败了)。

I recently started as a freelancer on my current project. One of the thing I threw myself on, was the failing Jenkins build (it was failing starting from April 8th, a week before I started here).

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

Generally speaking, you could see a buttload of DI issues in the log. First thing I did, was get all tests to work in the same way, starting from the same application context. They also implemented their own "mocking" thing, which seemed to fail to work correctly. After a discussion with the lead dev, I suggested to start using Springockito. (for a certain module, they needed mocking for their integration testing -- legacy reasons, which can't be changed)

无论如何,此后事情开始严重失败。测试中有很多被嘲笑的豆子,只是没有被嘲笑,或者没有被发现等等。通常,它将在加载应用程序上下文时失败,说明缺少一个或另一个bean。

Anyway, stuff started failing badly after that. A lot of beans which were mocked in the test, simply weren't mocked, or weren't found or whatever. Typically, it would fail on the loading of the application context, stating that one or another bean was missing.

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

I tried different stuff and different approaches, but in the end, only the thing I most feared would work: add @DirtiesContext to every single test. Now, the maven build is starting to turn green again, tests start doing what they are supposed to do. But I am reloading the Spring context each and every time, which takes time - which is all relative, since the context is loaded in about 1 - 2 seconds.

这个故事的一个侧面说明是它们已经升级到了Hibernate 4,因此也升级到了Spring 3.2。以前,他们使用的是Spring 3的旧版本。那时所有的测试都在工作,@ DirtiesContext并不是必需的。

A side note to this story is that they've upgraded to Hibernate 4, and thus to Spring 3.2. Previously, they were using an older version of Spring 3. All tests were working back then, and the @DirtiesContext thing was not necessary.

现在,最让我担心的是,我无法立即想到这种奇怪行为的解释。仅仅通过启动一个使用@Autowired bean的测试,似乎Springs上下文就被污染了。并非所有测试都使用Mocks,因此并非如此。
这听起来有人熟悉吗?有没有人在与Spring的最新版本进行集成测试方面有相同的经历?

Now, what worries me the most, is that I can't immediately think of an explanation for this weird behaviour. It almost seems that Springs context is dirtied, simply by launching a test which uses @Autowired beans. Not all tests are using Mocks, so it can't be that. Does this sound familiar to anyone? Has anyone had the same experiences with integration testing with (the latest version of) Spring?

在Stackoverflow上,我找到了这张票:如何测试Spring应用程序上下文中的脏内容?
似乎可以概括一下我所看到的行为,但关键是我们正在自动装配服务/存储库/ ...,并且这些类上没有任何设置方法。

On Stackoverflow, I've found this ticket: How can a test 'dirty' a spring application context? It seems to pretty much sum up the behaviour I'm seeing, but the point is that we're autowiring services/repositories/..., and that we don't have any setters on those classes whatsoever.

有什么想法吗?

谢谢!

推荐答案

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

To answer my own question, the secret was in the Spring version. We were using Spring 3.1.3, whereas I presumed they were using Spring 3.2 (they were constantly speaking about a recent upgrade of the Spring version).

解释在这里,我偶然发现一个博客文章以解决此问题: http://blog.springsource.org/2012/11/07/spring-framework-3- 2-rc1-new-testing-features /

The explanation was here, a blog post I stumbled over in my hunt to get it fixed: http://blog.springsource.org/2012/11/07/spring-framework-3-2-rc1-new-testing-features/

并粘贴相关内容的副本:

And a copy paste of the relevant piece:


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

The use of generic factory methods in Spring configuration is by no means specific to >testing, but generic factory methods such as EasyMock.createMock(MyService.class) or Mockito.mock(MyService.class) are often used to create dynamic mocks for Spring beans in a >test application context. For example, prior to Spring Framework 3.2 the following >configuration could fail to autowire the OrderRepository into the OrderService. The reason is >that, depending on the order in which beans are initialized in the application context, >Spring would potentially infer the type of the orderRepository bean to be java.lang.Object >instead of com.example.repository.OrderRepository.

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

So, how did I solve this problem? Well, I did the following steps:


  • 创建一个新的maven模块

  • 过滤掉测试需要嘲笑。所有未模拟的测试都将在Spring构建中正常运行,并在单独的Failsafe运行中运行(我创建了一个基本包 clean,并像这样对它们进行了分类)

  • 全部放入将模拟测试放在称为模拟的基本程序包中,并在Failsafe中对模拟测试进行额外的运行。

  • 每个模拟测试都使用Springockito创建模拟。我还使用了Springockito批注,可以轻松地就地执行@ReplaceWithMock。然后,每个模拟的测试都使用@DirtiesContext注释,因此在每个测试之后都会弄脏上下文,并且每个测试都会重新引入Spring上下文。

  • create a new maven module
  • filter out the tests which needed mocking. All the non-mocked test would run normallly in a Spring build, in a separate Failsafe run (I created a base-package "clean", and sorted them out like that)
  • Put all the mocked tests in a base package called "mocked", and make an additional run in Failsafe for the mocked tests.
  • Each mocked test is using Springockito, to create the mocks. I'm also using the Springockito annotations, to easily do a @ReplaceWithMock in place. Every mocked test is then annotated with @DirtiesContext, so the context is dirtied after each test, and the Spring context is reintroduced with each test.

我能给出的唯一合理的解释是,上下文实际上已经被弄脏了,因为有一个框架(Springockito)正在从Spring框架接管Spring bean的管理。我不知道这是否正确,但这是我能提出的最佳解释。实际上,这就是脏上下文的定义,这就是为什么我们需要将其标记为脏的原因。

The only reasonable explanation that I could give, is that the context is effectively being dirtied, because there is a framework (Springockito) which is taking over the management of the Spring beans from the Spring framework. I don't know if that's correct, but it's the best explanation I could come up with. That, in fact, is the definition of a dirty context, which is why we need to flag it as dirty.

使用这种策略,我建立并重新运行,所有测试都运行正常。它不是完美的,但是可以正常工作,而且是一致的。

Using this strategy, I got the build up and running again, and all tests are running ok. It's not perfect, but it's working, and it's consistent.

这篇关于每次集成测试后Spring上下文都很脏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆