【发布时间】:2021-05-15 12:36:28
【问题描述】:
上下文
- 将 gradle 从
5.5.1升级到7.0.2 - 经过测试 - 一切正常
- 将 spring 从 2.1.5 升级到 2.4.1
- 将测试注释从 junit 4 迁移到 junit 5
结果
- 单元测试工作
- 集成测试不要工作
问题
- 在应用程序上下文中重置 Mocks 时启动集成测试失败
@ResetMocksTestExecutionListneer.resetMocks - 有问题的 bean 的名称为
beanifyAuthenticationManager,其代理为interface org.springframework.security.authentication.AuthenticationManager- 检测此 bean 是否为
mock会陷入无限循环。 -
toString方法也是如此。
- 检测此 bean 是否为
问题
- 我做错了吗?
- 这是一个应该报告给 Spring 的问题吗?
其他信息
- 由定义为的自定义注释触发的集成测试
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SpringBootTest(
classes = {PmpTestApplication.class},
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
@ActiveProfiles(profiles = {"test"})
@TestExecutionListeners(value = {WithDomainAuthorizationExecutionListener.class},
mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
@TestPropertySource(properties = {
"spring.cloud.consul.enabled=false"})
public @interface AppIntTest {
- 集成测试看起来像
@AppIntTest
@ExtendWith(SpringExtension.class)
public class SomeRestBusinessControllerIntTest extends AbstractControllerIntTest {
- 实际的
StackOverflowError异常是从 引发的
AopTestUtils.getUltimateTargetObject
[...]
try {
if (AopUtils.isAopProxy(candidate) && candidate instanceof Advised) {
Object target = ((Advised) candidate).getTargetSource().getTarget();
if (target != null) {
return (T) getUltimateTargetObject(target);
}
}
}
catch (Throwable ex) {
throw new IllegalStateException("Failed to unwrap proxied object", ex);
}
[...]
很容易看出它是如何在 StackOverflowError 中运行的。
在再次递归调用 getUltimateTargetObject 之前需要检查 target <> candidate
【问题讨论】:
-
理论上,建议的
target <> candidate检查应该是不必要的,我想看看为什么/如何在您的场景中发生这种情况。因此,请在github.com/spring-projects/spring-framework/issues/new 上开票,并使用一个最小项目来复制StackOverflowError,我们(Spring 团队)将对其进行调查。 -
您可以尝试使用静态方法将
AuthenticationManagerbean 定义外部化到单独的配置类中吗?这通常有助于 bean 循环。
标签: spring mockito integration-testing junit5