I have some event publishing:
@Autowired private final ApplicationEventPublisher publisher;
...
publisher.publishEvent(new MyApplicationEvent(mySource));
I have this event listener:
class MyApplicationEventHandler {
@Autowired SomeDependency someDependency;
@EventListener public void processEvent(final MyApplicationEvent event) {
// handle event...
}
}
I need to test it using EasyMock. Is there a simple way to publish something in test and assert that my event listener did something?
EDIT:
I tried to create mock test like this:
// 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()));
}
It didn't work.
java.lang.AssertionError:
Expectation failure on verify:
SomeDependency.doSomething(<any>): expected: 1, actual: 0
Spring Boot microservices can be tested by using the JUnit testing framework, by annotating the test with @Test . Alternatively, to only load slices of functionality, use the @SpringBootTest annotation while listing the Spring components that participate in the test scenario in the annotation declaration.
You can test the event listener does its thing by instantiating the listener, then getting it to handle your event. // Create a listener instance. $listener = app()->make(YourListener::class); // or just app(YourListener::class) // Create an event instance.
Then, configure the Application context for the tests. The @Profile(“test”) annotation is used to configure the class when the Test cases are running. Now, you can write a Unit Test case for Order Service under the src/test/resources package. The complete code for build configuration file is given below.
First, As you're using Spring Boot, the testing of these becomes pretty straightforward. This test will spin up the boot context and inject a real instance of ApplicationEventPublisher, but create a mocked instance of SomeDependency. The test publishes the desired event, and verifies that your mock was invoked as you expected.
@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();
}
}
In case, spinning up the whole Spring context is not an option, with Spring Boot 2.0.0 ApplicationContextRunner
was introduced.
ApplicationContextRunner
can create an application context in your test, allowing for more control over the context.
A complete test example could be:
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 {}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With