I have problem with GwtMock and click handlers.
In my unit test I have a field with ClickHandler and Button:
@GwtMock private ClickHandler clickHandler;
My setUp method looks like:
@Before
public void setUp() {
when(this.display.getClearButton()).thenReturn(this.button);
when(this.display.getChangeStatusButton()).thenReturn(this.button);
}
And my test looks like:
@Test
public void shouldClearFilterAfterClickClearFilterButton() {
// given
when(this.button.addClickHandler(any(ClickHandler.class))).thenAnswer(new Answer<Object>() {
public Object answer(InvocationOnMock aInvocation) throws Throwable {
clickHandler = (ClickHandler) aInvocation.getArguments()[0];
return null;
}
});
this.presenter = new PresenterImpl(this.display, this.messages);
// when
clickHandler.onClick(clickEvent);
// then
this.presenter.asWidget();
}
Code which I would like to test looks like (I call this method from contructor):
private void addHandlers() {
this.display.getClearButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
clearFilter();
}
});
this.display.getChangeStatusButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
changeStatus();
}
});
}
The problem is that when I run a unit test I make a click event on button "ChangeStatus" but I want make a click event on button "Clear"
What is interesting when I change order of declaration handler then I can invoke code over the "Clear" button
How to solve this problem? How to call click event on particular buttons?
Let's read that code together:
getClearButton()
orgetChangeStatusButton()
is called, returnthis.button
; that is, the very same button for both method calls, which means you won't be able to tell which is which: it's just the same.addClickHandler
is called on that mock button, store the click handler in a field; that is, ifaddClickHandler
is called twice, the second call will overwrite the field with the second click handler, and you'll no longer reference the first one.getClearButton()
andgetChangeStatusButton()
and callsaddClickHandler
on both; that is, callsaddClickHandler
twice onthis.button
.Yes, that's exactly the expected behavior given your code. Use distinct mock buttons if you want to tell the buttons apart.
IMO, a better approach would be to, either: * make
getClearButton
andgetChangeStatusButton
returnHasClickHandlers
, so you don't even need GwtMockito and can just use bare Mockito. * refactor your code so that the view adds click handlers, the presenter is passed to the view, and the view can thus call presenter methods from the click handlers (e.g.presenter.clear()
andpresenter.changeStatus()
). For your presenter tests you can thus just call the presenter methods. Again, you no longer need gwtMockito and can just use bare Mockito. See http://www.gwtproject.org/articles/mvp-architecture-2.htmlAFAICT, GwtMockito is more suited to cases where you don't separate your view and presenter in code, and rather use UiBinder with the Java class playing the role of the presenter, and the
.ui.xml
being the view.