如何验证事件是否已使用 Spring、JUnit 和 Mockito 发布?
How do I verify that an event has been published using Spring, JUnit, and Mockito?
我正在使用 Spring 4.3.8.RELEASE 与 JUnit 4.12 和 Mockito 1.10.18。我有一个发布事件的服务......
@Service("organizationService")
@Transactional
public class OrganizationServiceImpl implements OrganizationService, ApplicationEventPublisherAware
publisher.publishEvent(new ZincOrganizationEvent(id));
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher)
{
this.publisher = publisher;
}
...
@Override
public void save(Organization organization)
{
...
publisher.publishEvent(new ThirdPartyEvent(organization.getId()));
我的问题是,如何在 JUnit 测试中验证事件是否已实际发布?
@Test
public void testUpdate()
{
m_orgSvc.save(org);
// Want to verify event publishing here
如果你想测试你是否没有忘记在你的 OrganizationServiceImpl
中调用 publishEvent
方法,你可以使用这样的东西:
class OrganizationServiceImplTest {
private OrganizationServiceImpl organizationService;
private ApplicationEventPublisher eventPublisher;
@Before
public void setUp() {
eventPublisher = mock(ApplicationEventPublisher.class);
organizationService = new OrganizationServiceImpl();
organizationService.setApplicationEventPublisher(eventPublisher)
}
@Test
public void testSave() {
/* ... */
organizationService.save(organization);
verify(eventPublisher).publishEvent(any(ThirdPartyEvent.class));
}
}
上面的测试用例将验证是否调用了 publishEvent
方法。
关于:
My question is, how do I verify in a JUnit test that an event has actually been published?
如果您想验证实际发送,您必须测试 ApplicationEventPublisher
实现并且可能没有模拟。
我更喜欢相反的方法,即更多 integration test-ey:
- ♂️使用 Mockito
模拟 ApplicationListener
- 将模拟应用程序侦听器注册到
ConfigurableApplicationContext
- 工作
- ✔验证模拟已收到事件
使用这种方法,您可以测试某个事件是否已通过某人接收的方式发布。
这是基本 身份验证测试的代码。在其他情况下,我测试是否发生了登录事件
@Test
public void testX509Authentication() throws Exception
{
ApplicationListener<UserLoginEvent> loginListener = mock(ApplicationListener.class);
configurableApplicationContext.addApplicationListener(loginListener);
getMockMvc().perform(get("/").with(x509(getDemoCrt())))//
.andExpect(status().is3xxRedirection())//
.andExpect(redirectedUrlPattern("/secure/**"));
getErrorCollector().checkSucceeds(() -> {
verify(loginListener, atLeastOnce()).onApplicationEvent(any(UserLoginEvent.class));
return null;
});
}
我的建议是释放 Mockito 的力量来深入验证事件参数。就我而言,我会将我的代码扩展为:
- 检查登录事件中的用户名是否与经过身份验证的主体匹配
- 在用户明显无法登录的情况下执行额外的测试,我会期待各种登录失败事件之一
我正在使用 Spring 4.3.8.RELEASE 与 JUnit 4.12 和 Mockito 1.10.18。我有一个发布事件的服务......
@Service("organizationService")
@Transactional
public class OrganizationServiceImpl implements OrganizationService, ApplicationEventPublisherAware
publisher.publishEvent(new ZincOrganizationEvent(id));
@Override
public void setApplicationEventPublisher(ApplicationEventPublisher publisher)
{
this.publisher = publisher;
}
...
@Override
public void save(Organization organization)
{
...
publisher.publishEvent(new ThirdPartyEvent(organization.getId()));
我的问题是,如何在 JUnit 测试中验证事件是否已实际发布?
@Test
public void testUpdate()
{
m_orgSvc.save(org);
// Want to verify event publishing here
如果你想测试你是否没有忘记在你的 OrganizationServiceImpl
中调用 publishEvent
方法,你可以使用这样的东西:
class OrganizationServiceImplTest {
private OrganizationServiceImpl organizationService;
private ApplicationEventPublisher eventPublisher;
@Before
public void setUp() {
eventPublisher = mock(ApplicationEventPublisher.class);
organizationService = new OrganizationServiceImpl();
organizationService.setApplicationEventPublisher(eventPublisher)
}
@Test
public void testSave() {
/* ... */
organizationService.save(organization);
verify(eventPublisher).publishEvent(any(ThirdPartyEvent.class));
}
}
上面的测试用例将验证是否调用了 publishEvent
方法。
关于:
My question is, how do I verify in a JUnit test that an event has actually been published?
如果您想验证实际发送,您必须测试 ApplicationEventPublisher
实现并且可能没有模拟。
我更喜欢相反的方法,即更多 integration test-ey:
- ♂️使用 Mockito 模拟
- 将模拟应用程序侦听器注册到
ConfigurableApplicationContext
- 工作
- ✔验证模拟已收到事件
ApplicationListener
使用这种方法,您可以测试某个事件是否已通过某人接收的方式发布。
这是基本 身份验证测试的代码。在其他情况下,我测试是否发生了登录事件
@Test
public void testX509Authentication() throws Exception
{
ApplicationListener<UserLoginEvent> loginListener = mock(ApplicationListener.class);
configurableApplicationContext.addApplicationListener(loginListener);
getMockMvc().perform(get("/").with(x509(getDemoCrt())))//
.andExpect(status().is3xxRedirection())//
.andExpect(redirectedUrlPattern("/secure/**"));
getErrorCollector().checkSucceeds(() -> {
verify(loginListener, atLeastOnce()).onApplicationEvent(any(UserLoginEvent.class));
return null;
});
}
我的建议是释放 Mockito 的力量来深入验证事件参数。就我而言,我会将我的代码扩展为:
- 检查登录事件中的用户名是否与经过身份验证的主体匹配
- 在用户明显无法登录的情况下执行额外的测试,我会期待各种登录失败事件之一