Resteasy-Spring:在使用多个 运行 实例进行测试期间加载了不正确的应用程序实例
Resteasy-Spring: incorrect app instance loaded during tests with multiple running instances
问题简短摘要:
我写了一个简单的 REST HTTP 接口,用 Spring Boot 构建,其中 returns 调用 GET /app
时的简单文本响应,基于 ClientInterface
的实现],其中有2个。REST能力是使用JAX-RS实现的,由resteasy通过RestEasy-SpringBoot library.
提供
我还写了 3 个测试,其中第 3 个失败了,因为 响应来自 ClientInterface
的第二个实现而不是第一个实现,因为(我假设)Resteasy正在混淆应用程序实例,因此加载了不正确的 Spring 应用程序上下文,以及不正确的 beans.
注意:您可以找到示例应用程序 here,其中还包括文档
请查看源代码以获得清晰的图片。把代码也贴进去会占用太多space
更多详情:
ClientInterface
有 2 个实现,它们提供 REST 资源给出的响应。它们使用 client-impl-two
配置文件切换。如果配置文件不存在,则使用第一个实现,如果存在,则使用第二个。
first 和 third 测试期望第一个实现的响应,second 测试需要秒实现的响应,因为它使用的是 client-two-impl
配置文件。
当我 运行 使用 IntelliJ 的 JUnit 集成进行测试时,第三个失败:
您会注意到测试的命名方式使其强制执行特定的执行顺序,这是相关的,因为第三个测试仅在第二个测试之后执行时才会失败。它失败了,因为它得到了第二个 ClientInterface
实现的响应, 即使第三个测试没有使用 client-impl-two
配置文件 .
到目前为止我有什么done/discovered:
- 有时,运行ning
./mvnw clean test
也有同样的错误结果,但我一直无法提供可重现的例子
- Spring 应用程序上下文已由 Spring/Spring 引导正确加载
- Spring 引导正确注入端口号,测试中的其余客户端始终调用它们应该调用的 REST 实例
- 只有当 Resteasy 接管请求时,它才会以某种方式加载不正确的应用程序实例,因此使用了不正确的 Spring 应用程序上下文,这就是它给出错误响应的原因
- 这是我通过在 SpringResourceFactory.createResource() 中保留一个断点来解决的,它只是查询资源 bean 的
beanFactory
,然后调用 beanFactory.getBean(ClientInterface.class)
看看出现了哪个实现,第三次测试是错误的
- 在测试期间,应用程序 运行ning 有多个实例,每个都在其自己的端口上,我认为这与问题有关
- 还有一个分支,
jersey-instead-of-resteasy
,其中 Jersey 被用作 JAX-RS 实现,无论是 运行 使用 IntelliJ 还是使用 Maven
- 有一个
DebugFilter
,我用它检查 Spring 应用程序上下文在请求被 Resteasy servlet 接管之前的样子,它总是正确的(正确的实现ClientInterface
的加载),无论测试如何执行
- 只有当运行进行第三次测试时,当请求到达 Resteasy 时,才会加载不正确的应用程序实例,如以上几点之一所述
基于以上几点,我强烈怀疑 Resteasy 可能是问题所在。
非常感谢任何帮助。
我对此进行了一些调试,我认为失败是由 resteasy-spring-boot-starter 中的错误引起的。我刚刚在 github 上创建了一个问题并提供了一个 PR [2] 来修复它并使您的测试通过。
我也在评论 [3]。感谢出色的描述和复制者。
问题简短摘要:
我写了一个简单的 REST HTTP 接口,用 Spring Boot 构建,其中 returns 调用 GET /app
时的简单文本响应,基于 ClientInterface
的实现],其中有2个。REST能力是使用JAX-RS实现的,由resteasy通过RestEasy-SpringBoot library.
我还写了 3 个测试,其中第 3 个失败了,因为 响应来自 ClientInterface
的第二个实现而不是第一个实现,因为(我假设)Resteasy正在混淆应用程序实例,因此加载了不正确的 Spring 应用程序上下文,以及不正确的 beans.
注意:您可以找到示例应用程序 here,其中还包括文档
请查看源代码以获得清晰的图片。把代码也贴进去会占用太多space
更多详情:
ClientInterface
有 2 个实现,它们提供 REST 资源给出的响应。它们使用 client-impl-two
配置文件切换。如果配置文件不存在,则使用第一个实现,如果存在,则使用第二个。
first 和 third 测试期望第一个实现的响应,second 测试需要秒实现的响应,因为它使用的是 client-two-impl
配置文件。
当我 运行 使用 IntelliJ 的 JUnit 集成进行测试时,第三个失败:
您会注意到测试的命名方式使其强制执行特定的执行顺序,这是相关的,因为第三个测试仅在第二个测试之后执行时才会失败。它失败了,因为它得到了第二个 ClientInterface
实现的响应, 即使第三个测试没有使用 client-impl-two
配置文件 .
到目前为止我有什么done/discovered:
- 有时,运行ning
./mvnw clean test
也有同样的错误结果,但我一直无法提供可重现的例子 - Spring 应用程序上下文已由 Spring/Spring 引导正确加载
- Spring 引导正确注入端口号,测试中的其余客户端始终调用它们应该调用的 REST 实例
- 只有当 Resteasy 接管请求时,它才会以某种方式加载不正确的应用程序实例,因此使用了不正确的 Spring 应用程序上下文,这就是它给出错误响应的原因
- 这是我通过在 SpringResourceFactory.createResource() 中保留一个断点来解决的,它只是查询资源 bean 的
beanFactory
,然后调用beanFactory.getBean(ClientInterface.class)
看看出现了哪个实现,第三次测试是错误的
- 这是我通过在 SpringResourceFactory.createResource() 中保留一个断点来解决的,它只是查询资源 bean 的
- 在测试期间,应用程序 运行ning 有多个实例,每个都在其自己的端口上,我认为这与问题有关
- 还有一个分支,
jersey-instead-of-resteasy
,其中 Jersey 被用作 JAX-RS 实现,无论是 运行 使用 IntelliJ 还是使用 Maven - 有一个
DebugFilter
,我用它检查 Spring 应用程序上下文在请求被 Resteasy servlet 接管之前的样子,它总是正确的(正确的实现ClientInterface
的加载),无论测试如何执行- 只有当运行进行第三次测试时,当请求到达 Resteasy 时,才会加载不正确的应用程序实例,如以上几点之一所述
基于以上几点,我强烈怀疑 Resteasy 可能是问题所在。
非常感谢任何帮助。
我对此进行了一些调试,我认为失败是由 resteasy-spring-boot-starter 中的错误引起的。我刚刚在 github 上创建了一个问题并提供了一个 PR [2] 来修复它并使您的测试通过。 我也在评论 [3]。感谢出色的描述和复制者。