尝试在 Junit 测试中注入带有注释 @MockBean 的 bean 时,我遇到了一些问题。结果,我注入了真正的服务而不是模拟的服务,但奇怪的行为是,这只发生在使用 maven verify 运行测试时(与其他集成测试一起)。
基本上,我要模拟的 bean 被注入到侦听器 (@Component) 中,该侦听器由集成测试期间在队列上发送的消息触发。当监听器运行时,它里面的服务是真实的,而不是模拟的。
在我看来,在运行其他测试时,真正的 bean 先前被注入到上下文中,@MockBean 虽然应该重新启动 spring 上下文,但在遇到相同的 bean 时不会用模拟的 bean 替换现有的 bean类型。
这确实是一个奇怪的行为,因为文档说“在上下文中定义的任何现有的相同类型的单个 bean 都将被模拟替换”。好吧,这不会发生。
您可以在下面找到显示这是如何完成的片段。
要模拟的服务是:
@Slf4j
@Service
@Transactional
public class SomeServiceImpl implements SomeService {
@Override
@Async
public void doStuff(){
...
}
}
像这样注入我的服务的侦听器
@Slf4j
@Component
@Transactional
public class SagaListener {
@Autowired
private SomeService someService;
@JmsListener(destination = "${mydestinationtopic}", containerFactory = "myFactory",
subscription = "my-subscription", selector = "eventType =
'MY_EVENT'" )
public void receive(MyEventClass event) {
someService.doStuff();
}
}
这是我的测试课
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class SagaListenerIT {
@MockBean
private SomeService someService;
@Autowired
private Sender sender;
@Test
public void createNamespaceSuccess() throws InterruptedException {
...
sender.send(event, event.getEventType(), myTopic);
BDDMockito.then(someService).should().doStuff();
}
}
结果,我得到那个 mockito 说 someService 进行了 0 次调用,这是因为正在调用真正的服务。
为什么@MockBean 不替换真正的bean?不应该重新初始化上下文吗?
我尝试在其他测试中添加 @DirtiesContext 注释,在这种情况下一切正常,但这不是一个干净的解决方案。
这是我的 pom 的一部分,其中定义了故障安全插件。顺便说一句,这很简单:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
</executions>
</plugin>
谢谢