-
Notifications
You must be signed in to change notification settings - Fork 0
Mocking
Sometimes, you may be writing unit tests for a class that has dependencies to other classes, and that interact with them via method calls. In this case, you might want to use mock objets instead of real objects for these classes : they allow you to test that the right method calls were made, instead of testing the actual behavior of the objects.
gwt-test-utils allows you to write unit tests that use mock objects, using either the EasyMock or the Mockito mocking framework.
Mocking support consists in three main features :
-
Obtaining mock objets when using deferred binding : when declaring mock objects in your test class, you're telling gwt-test-utils that
GWT.create(Class clazz)
deferred binding made in your application code should return the mock object of the corresponding type, declared in test class. - RPC calls/callbacks stubbing : shortcut methods that ease the mocking of RPC calls and the handling of callbacks in tests.
- Helper methods : a few methods to ease some mocking operations, particularly when using EasyMock.
We will modify the previous sample to use an external ClientGreeting
object to say hello.
<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui">
<g:HTMLPanel>
<g:TextBox ui:field="textBox"></g:TextBox>
<g:Button ui:field="button">Say Hello RPC</g:Button>
<g:Label ui:field="label" />
</g:HTMLPanel>
</ui:UiBinder>
public class MockSampleView extends Composite {
interface MockSampleViewUiBinder extends UiBinder<Widget, MockSampleView> { }
private static MockSampleViewUiBinder uiBinder = GWT.create(MockSampleViewUiBinder.class);
@UiField
Button button;
@UiField
Label label;
@UiField
TextBox textBox;
private final ClientGreeting clientGreeting;
public MockSampleView(ClientGreeting clientGreeting) {
this.clientGreeting = clientGreeting;
initWidget(uiBinder.createAndBindUi(this));
label.setVisible(false);
button.setEnabled(false);
}
@UiHandler("button")
void onClick(ClickEvent e) {
label.setText(clientGreeting.greet(textBox.getText()));
label.setVisible(true);
}
@UiHandler("textBox")
void onKeyPress(KeyUpEvent e) {
button.setEnabled(textBox.getText().trim().length() > 0);
label.setVisible(false);
}
}
public class ClientGreeting {
public String greet(String name) {
return "ClientGreeting says hello " + name;
}
}
- Add the EasyMock maven dependency :
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.0</version>
<scope>test</scope>
</dependency>
-
In order to use the EasyMock mocking framework, your tests need to extend
GwtTestWithEasyMock
. -
Declare your mock objets using gwt-test-utils's own
@Mock
annotation.
@GwtModule("com.googlecode.gwt.test.sample.MockSample")
public class MockSampleViewWithEasyMockTest extends GwtTestWithEasyMock {
@Mock
private ClientGreeting clientGreeting;
@Test
public void clickOnButtonShouldDisplayMessageInLabel() {
// Arrange
MockSampleView view = new MockSampleView(clientGreeting);
view.textBox.setText("Ben Linus");
view.button.setEnabled(true);
assertThat(view.label).isNotVisible();
// expect object invocation
EasyMock.expect(clientGreeting.greet(EasyMock.eq("Ben Linus"))).andReturn("Mocked hello message");
// EasyMock.replay(..) for every @Mock objects
replay();
// Act
Browser.click(view.button);
// Assert
// EasyMock.verify(..) for every @Mock objects
verify();
assertThat(view.label).isVisible().textEquals("Mocked hello message");
}
}
-
@Mock
tells gwt-test-utils to create a mock object using EasyMock. -
replay()
will callEasyMock.replay(..)
on each declared@Mock
in the test class. -
verify()
will callEasyMock.verify(..)
on each declared@Mock
in the test class.
Of course, you can also use the EasyMock API rather than methods provided by GwtTestWithEasyMock
.
Warning : mock objects not declared using the @Mock
annotation (e.g. objects instantiated by calling directly the EasyMock.createMock()
method) should be added to the test context using the GwtTestWithMocks#addMockedObject()
method.
- Add the Mockito maven dependency :
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>1.8.5</version>
<scope>test</scope>
</dependency>
-
In order to use the Mockito mocking framework, your tests need to extend
GwtTestWithMockito
. -
Declare your mock objets using gwt-test-utils's or Mockito
@Mock
annotation.
@GwtModule("com.googlecode.gwt.test.sample.MockSample")
public class MockSampleViewWithMockitoTest extends GwtTestWithMockito {
@Mock
private ClientGreeting clientGreeting;
@Test
public void clickOnButtonShouldDisplayMessageInLabel() {
// Arrange
MockSampleView view = new MockSampleView(clientGreeting);
view.textBox.setText("Ben Linus");
view.button.setEnabled(true);
assertThat(view.label).isNotVisible();
// expect object invocation
Mockito.when(clientGreeting.greet(Mockito.eq("Ben Linus"))).thenReturn("Mocked hello message");
// Act
Browser.click(view.button);
// Assert
Mockito.verify(clientGreeting).greet(Mockito.eq("Ben Linus"));
assertThat(view.label).isVisible().textEquals("Mocked hello message");
}
}
-
@Mock
tells gwt-test-utils to create a mock object using Mockito. Both gwt-test-utils or Mockito annotation can be used. -
Mockito.verify(Object mock)
checks thegreet()
method was actually called with expected parameters.
Warning : mock objects not declared using the @Mock
annotation (e.g. objects instantiated by calling directly the Mockito.mock()
method) should be added to the test context using the GwtTestWithMocks#addMockedObject()
method.
Sources of this sample are available here.