gpt4 book ai didi

java - 在测试中使用@MockBean 会强制重新加载应用程序上下文

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:19:23 29 4
gpt4 key购买 nike

我在 Spring Framework 上运行了几个集成测试,它们扩展了名为 BaseITCase 的基类。
像这样:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {AppCacheConfiguration.class, TestConfiguration.class}, loader = SpringBootContextLoader.class)
@Transactional
@WebMvcTest
public abstract class BaseITCase{...}
...
public class UserControllerTest extends BaseITCase {...}

问题是其中一个测试有几个声明:@MockBean 在它里面并且在这个测试执行的那一刻,Spring 重新创建上下文,并且这个测试之后的测试有时会使用错误的 beans(来自为使用 @MockBean 的测试创建的上下文)。我只是通过检查 bean 是否具有不同的哈希码才发现了这一点。

当我使用@EventListener 时,它变得非常重要。因为调用了错误上下文(已经完成执行的测试类的上下文)的监听器,所以我在那里有错误的 bean。

有什么解决方法吗?

我试图将所有@MockBean 声明移动到基本类,但它工作正常,因为没有创建新的上下文。但是,它使基础课太重了。另外,我试图为这个测试创建一个脏上下文,但是下一个测试失败并显示上下文已经关闭的消息。

最佳答案

原因是带有@MockBean的测试的spring配置与其余测试不同,所以spring框架无法缓存之前使用过的context,需要重新加载。在这里你可以找到更详细的解释:https://github.com/spring-projects/spring-boot/issues/10015

如您所说,如果将模拟 bean 移至父类,上下文不会重新加载,这是有道理的,因为 bean 配置保持不变。

一个可能的解决方法是将您的模拟 bean 定义为一个简单的模拟并在需要的地方手动注入(inject)它。

例如,UserController 依赖于 Foo:

public class UserControllerTest extends BaseITCase {

private Foo foo = Mockito.mock(Foo.class);

@Autowired
private UserController userController;

@Before
public void setUp() {
super.setup();

this.userController.setFoo(foo);
}
}

@Component
public class UserController {

private Foo foo;

@Autowired
public void setFoo(final Foo foo) {
this.foo = foo;
}
}

希望这对您有所帮助。

关于java - 在测试中使用@MockBean 会强制重新加载应用程序上下文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45587213/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com