Resteasy-Spring:在具有多个运行实例的测试期间加载了错误的应用实例

Gab*_*uiu 5 spring intellij-idea resteasy spring-boot

问题简短摘要:

我编写了一个简单的REST HTTP接口,使用Spring Boot构建,在调用时返回一个简单的文本响应GET /app,基于其实现ClientInterface,其中有2个.REST功能是使用JAX-RS实现的,由resteasy通过RestEasy-SpringBoot库.

我还编写了3个测试,其中第3个失败,因为响应来自第二个实现,ClientInterface而不是第一个实现,因为(我假设)Resteasy混合了应用程序实例,因此错误的Spring Application上下文是使用错误的bean加载.

注意:您可以在此处找到示例应用程序,其中还包括文档

请查看源代码以获得清晰的图片.它也会占用太多空间来粘贴代码.

更多细节:

有两个实现ClientInterface提供REST资源给出的响应.使用client-impl-two配置文件切换它们.如果配置文件不存在,则使用第一个实现,如果存在,则使用第二个实现.

一个第三个测试期望第一个实现的响应,第二个测试期望秒实现的响应,因为它正在使用client-two-impl配置文件.

当我使用IntelliJ的JUnit集成运行测试时,第三个失败: 在此输入图像描述 在此输入图像描述

您会注意到测试被命名为强制执行某个执行顺序,这是相关的,因为第三个测试仅在第二个测试执行后才会失败.并且它失败了,因为它得到了第二个ClientInterface实现的响应,即使第三个测试不使用client-impl-two配置文件.

到目前为止我做了/发现了什么:

  • 有时,运行./mvnw clean test也有相同的错误结果,但我无法提供可重现的示例
  • Spring/Spring Boot正确加载了Spring Application上下文
  • Spring Boot正确地注入端口号,测试中的其余客户端总是调用它们应该的REST实例
  • 只有当Resteasy接管请求时,它才会以某种方式加载应用程序的错误实例,因此使用了错误的Spring Application上下文,这就是为什么它会给出不正确的响应
    • 我通过在SpringResourceFactory.createResource()中保留一个断点来解决这个问题,它只是beanFactory对资源bean进行querynig ,并调用beanFactory.getBean(ClientInterface.class)以查看哪个实现出现了,并且对于第三个测试它是不正确的
  • 在测试期间,有多个应用程序运行实例,每个实例都在自己的端口上,我认为这个问题与问题有关
  • 还有另一个分支,jersey-instead-of-resteasy其中Jersey被用作JAX-RS实现,并且无论是使用IntelliJ还是使用Maven运行测试都是成功的
  • 有一个DebugFilter与我检查Spring应用程序上下文的样子是由RestEasy的servlet的接管请求之前,它始终是正确的(正确执行的ClientInterface加载),无论测试如何执行
    • 只有在运行第三次测试时,当请求到达Resteasy时,才会加载不正确的应用实例,如上述其中一项所述

基于以上几点,我强烈怀疑Resteasy可能是个问题.

任何帮助是极大的赞赏.

小智 2

我对此进行了一些调试,我相信失败是由resteasy-spring-boot-starter 中的错误引起的。我刚刚在 github 上创建了一个问题,并提供了一个 PR [2] 来修复它并使您的测试通过。我也在评论[3]。感谢精彩的描述和复制者。

  1. https://github.com/paypal/resteasy-spring-boot/issues/51
  2. https://github.com/paypal/resteasy-spring-boot/pull/52
  3. https://issues.jboss.org/browse/RESTEASY-1595

  • 版本 2.2.2-RELEASE 刚刚发布并修复了该问题。 (2认同)