当尝试在 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(){
...
}
}
Run Code Online (Sandbox Code Playgroud)
像这样注入我的服务的侦听器
@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();
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的测试课
@Slf4j
@SpringBootTest
@RunWith(SpringRunner.class)
public class SagaListenerIT …Run Code Online (Sandbox Code Playgroud) 我想基于事件通用类型构建事件处理。
活动类别:
public class PushNotificationStoreEvent<T extends Push> extends ApplicationEvent {
private static final long serialVersionUID = -3791059956099310853L;
public T push;
public PushNotificationStoreEvent(Object source, T push) {
super(source);
this.push = push;
}
}
Run Code Online (Sandbox Code Playgroud)
这Push是类的标记接口:PushNotificationNew和PushNotificationFail。
听众:
@Async
@EventListener
public void storeNewPush(PushNotificationStoreEvent<PushNotificationNew> event) {
pushNewRepoService.save(event.push);
}
@Async
@EventListener
public void storeFailPush(PushNotificationStoreEvent<PushNotificationFail> event) {
pushFailRepoService.save(event.push);
}
Run Code Online (Sandbox Code Playgroud)
PushNotificationStoreEvent<PushNotificationNew>问题:听众之间和听众之间没有区别PushNotificationStoreEvent<PushNotificationFail> 。
这意味着所有事件PushNotificationStoreEvent都由所有侦听器处理。
我可以通过为每个案例创建单独的事件类或使用一个监听器并选择正确的操作来解决这个instanceof问题event.push。也许您知道更好的解决方案?