dve*_*opp 9 java spring spring-test mockito springmockito
我在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 {...}
Run Code Online (Sandbox Code Playgroud)
问题是其中一个测试有几个声明:@MockBean在它内部以及执行此测试的那一刻,Spring重新创建上下文,并且在此之后的测试有时使用错误的bean(来自为@的测试创建的上下文) MockBean).我通过检查bean有不同的哈希码来发现这一点.
当我使用@EventListener时,它变得非常关键.因为调用了错误上下文(已经完成执行的测试类的上下文)的侦听器,并且我在那里有错误的bean.
那有什么解决方法吗?
我试图将所有@MockBean声明移动到基本类,它工作正常,因为没有创建新的上下文.但是,它使基础课太重了.此外,我尝试为此测试创建一个脏上下文,但接下来的测试失败,并显示上下文已被关闭的消息.
小智 8
原因是具有@MockBean的测试的spring配置与其他测试不同,因此spring框架无法缓存以前使用的上下文并需要再次加载它.在这里您可以找到更详细的解释:https://github.com/spring-projects/spring-boot/issues/10015
正如您所说,如果您将模拟bean移动到父类,则不会重新加载上下文,这有意义,因为bean配置保持不变.
一种可能的解决方法是将您的模拟bean定义为一个简单的模拟,并在需要的地方手动注入它.
例如,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;
}
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
@MockBean
可能会导致上下文重新加载,如前面的答案中所述。
作为替代方案,如果您使用的是 spring boot 2.2+,则可以使用@MockInBean而不是@MockBean
. 它使您的上下文保持干净,并且不需要重新加载您的上下文。
@SpringBootTest\npublic class UserControllerTest extends BaseITCase {\n\n\xc2\xa0 \xc2\xa0 @MockInBean(UserController.class)\n\xc2\xa0 \xc2\xa0 private Foo foo;\n\n\xc2\xa0 \xc2\xa0 @Autowired\n\xc2\xa0 \xc2\xa0 private UserController userController;\n\n\xc2\xa0 \xc2\xa0 @Test\n\xc2\xa0 \xc2\xa0 public void test() {\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0 userController.doSomething();\n\xc2\xa0 \xc2\xa0 \xc2\xa0 \xc2\xa0 Mockito.verify(foo).hasDoneSomething();\n\xc2\xa0 \xc2\xa0 }\n}\n\n@Component\npublic class UserController {\n\n\xc2\xa0 \xc2\xa0 @Autowired\n\xc2\xa0 \xc2\xa0 private Foo foo;\n\n}\n
Run Code Online (Sandbox Code Playgroud)\n免责声明:我创建这个库的目的正是为了:在 Spring beans 中模拟 beans 并避免冗长的上下文重新创建。
\n 归档时间: |
|
查看次数: |
2929 次 |
最近记录: |