Unittest verify public observable behavior where "public" means through the units API and "behavior" meand return values and/or communication with dependencies.
Your code has a hidden dependecy intoduced by the static access to the EventHandler
object. I assume that your EventHandler
class incorporates the Java singelton pattern. This is STUPID code most of us have been started with.
You should not surrender to this bad design by using PowerMock.
The better way would be to pass an EventHandler
object as constructor parameter to your code under test like this:
class MyTestedClass{
private final EventHandler eventHandler;
class MyTestedClass(EventHandler eventHandler){
this.eventHandler=eventHandler;
}
public void handleSomeEvent(String str1, String str2){
MyObject obj1 = new MyObject();
obj1.setParameterA(str1);
obj2.setParameterB(str2);
eventHandler.notify(obj1)
}
}
And then make your EventHandler
a normal class that you can inherit from. (at least remofe the final
key word from the class declaration).
Then you could use plain Mockito to replace the EventHandler
object with a test double and verify your codes comunication with that test double:
class MyTestedClassTest{
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
@Mock private EventHandler eventHandler; // ignores the private constructor
class MyTestedClass(EventHandler eventHandler){
this.eventHandler=eventHandler;
}
@Test
public void notifiesEventHandlerWithDTO(String str1, String str2){
new UnderTest(eventHandler).handleSomeEvent("test1","test2");
ArgumentCaptor<MyObject> handlerArg = ArgumentCaptor.forClass(MyObject.class);
verify(eventHandler).notify(handlerArg.capture());
assertThat("parameter A passed to object",
handlerArg.getValue().getParameterA(),
equalTo("test1"));
assertThat("parameter B passed to object",
handlerArg.getValue().getParameterB(),
equalTo("test2"));
}
}