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()
or getChangeStatusButton()
is called, return this.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, if addClickHandler
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()
and getChangeStatusButton()
and calls addClickHandler
on both; that is, calls addClickHandler
twice on this.button
.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
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
and getChangeStatusButton
return HasClickHandlers
, 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()
and presenter.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.html
AFAICT, 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.