我有一些活动发布:
@Autowired private final ApplicationEventPublisher publisher;
...
publisher.publishEvent(new MyApplicationEvent(mySource));
我有此事件侦听器:
class MyApplicationEventHandler {
@Autowired SomeDependency someDependency;
@EventListener public void processEvent(final MyApplicationEvent event) {
// handle event...
}
}
我需要使用EasyMock对其进行测试。有没有一种简单的方法可以在测试中发布某些内容并断言我的事件侦听器做了什么?
编辑:
我试图创建这样的模拟测试:
// testing class
SomeDependency someDependency = mock(SomeDependency.class);
MyApplicationEventHandler tested = new MyApplicationEventHandler(someDependency);
@Autowired private final ApplicationEventPublisher publisher;
@Test
public void test() {
someDependency.doSomething(anyObject(SomeClass.class));
replay();
publisher.publishEvent(new MyApplicationEvent(createMySource()));
}
没有用。
java.lang.AssertionError:
Expectation failure on verify:
SomeDependency.doSomething(<any>): expected: 1, actual: 0
答案 0 :(得分:6)
以防万一,不能选择扩展整个Spring上下文,因此引入了Spring Boot 2.0.0 ApplicationContextRunner
。
ApplicationContextRunner
可以在测试中创建应用程序上下文,从而可以对上下文进行更多控制。
完整的测试示例可以是:
package net.andreaskluth.context.sample;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
public class SimpleEventTest {
private final ApplicationContextRunner runner = new ApplicationContextRunner();
@Test
public void happyPathSuccess() {
AtomicBoolean sideEffectCausedByEvent = new AtomicBoolean(false);
ObservableEffect effect = () -> sideEffectCausedByEvent.set(true);
runner
.withBean(SomeEventListener.class, effect)
.run(
context -> {
context.publishEvent(new SomeEvent());
assertThat(sideEffectCausedByEvent.get()).isTrue();
});
}
public interface ObservableEffect {
void effect();
}
@Component
public static class SomeEventListener {
private final ObservableEffect effect;
public SomeEventListener(ObservableEffect effect) {
this.effect = effect;
}
@EventListener(SomeEvent.class)
public void listen() {
effect.effect();
}
}
public static class SomeEvent {}
}
答案 1 :(得分:2)
首先,当您使用Spring Boot时,对它们的测试变得非常简单。此测试将启动引导上下文并注入ApplicationEventPublisher的真实实例,但创建模拟的SomeDependency实例。该测试将发布所需的事件,并验证您的模拟是否按预期被调用。
@RunWith(SpringRunner.class)
@SpringBootTest
public class EventPublisherTest {
@Autowired
private final ApplicationEventPublisher publisher;
@MockBean
private SomeDependency someDependency;
@Test
public void test() {
publisher.publishEvent(new MyApplicationEvent(createMySource()));
// verify that your method in you
verify(someDependency, times(1)).someMethod();
}
}
答案 2 :(得分:0)
我采取的选择是在测试本身中创建一个TestConfiguration和一个侦听器,如下所示:
@Slf4j
@ExtendWith(SpringExtension.class)
@SpringBootTest(classes = {RegistrationConfiguration.class, RegistrationTestConfiguration.class})
class RegistrationServiceIntegrationTest {
@Autowired
private DynamoDBMapper dynamoDBMapper;
@Autowired
private AmazonDynamoDBAsync amazonDynamoDB;
@Autowired
private RegistrationRepository repository;
@Autowired
private ApplicationEventPublisher eventPublisher;
private String personaId;
private RegistrationService testObj = null;
@BeforeEach void setup() {
RegistrationServiceDBHelper.initializeTable(dynamoDBMapper, amazonDynamoDB, repository);
personaId = UUID.randomUUID().toString();
testObj = new RegistrationService(repository, eventPublisher);
}
@TestConfiguration
static class RegistrationTestConfiguration {
@Bean
RegistrationServiceEventListener eventListener() {
return new RegistrationServiceEventListener();
}
}
@Component
public static class RegistrationServiceEventListener {
@TransactionalEventListener
public void onPlayerRegisteredEvent(PlayerRegisteredEvent event) {
log.info("Received new user event {}", event.personaId());
assertThat(event.personaId()).isNotBlank();
}
}
@DisplayName("given a persona id that is not registered")
@Nested class WhenNoPlayerIsRegistered {
@DisplayName("when a player is registered"
+ " then an event is raised")
@Test void raisePlayerRegisteredEvent() {
// When
testObj.registerPlayer(personaId);
}
}
}