Comprehensive Pros/Cons of Mocking Frameworks for GWT - java

I'm interested in using the right mocking framework for my GWT app. It's my understanding that Mockito, EasyMock, and jMock are some of the most popular for Java. Could someone list pros/cons for the mocking framework that they are most familiar with as it relates to GWT to help fellow GWT testing noobs like myself?
Thanks in advance.

For the server side testing (RPC services) you can use any mocking framework you wish. spring-test library might be useful for mocking HttpRequest, HttpSession, and other classes of servlet api. Still you might have problems with testing classes extending RemoteServiceServlet, as they require properly encoded request. Here is interesting project which solves this problem:
http://www.gdevelop.com/w/blog/2010/01/10/testing-gwt-rpc-services/
When it comes to testing of client side GWT code (the part which is compiled into Java Script), you can extend GWTTestCase. However due to limited emulation of JRE library, lack of reflection API in particular, it would be impossible to use any mocking framework. What is more, GWTTestCase runtime is very slow, and for this reason consider as a base for integration testing rather than unit testing.
It is possible to create unit tests for GWT client code if GWT application follows Model View Presenter pattern. Assuming we are testing so called "Presenter" (logic) we can mock so called "Display" with any mocking framework. Here is example unit test using Mockito:
import static org.mockito.BDDMockito.*;
import org.junit.Test;
import com.google.gwt.user.client.ui.HasText;
public class ResultPresenterTest {
#Test
public void shouldSetItWorksResultText() {
// given
ResultPresenter.Display display = mock(ResultPresenter.Display.class);
MockButton button = new MockButton();
HasText label = mock(HasText.class);
given(display.getShowResultButton()).willReturn(button);
given(display.getResultLabel()).willReturn(label);
ResultPresenter presenter = new ResultPresenter();
presenter.bind(display);
// when
button.click();
// then
verify(label).setText("It works");
}
}
Here is the presenter:
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.ui.HasText;
public class ResultPresenter {
private Display display;
public interface Display {
HasClickHandlers getShowResultButton();
HasText getResultLabel();
}
public void bind(final Display display) {
this.display = display;
display.getShowResultButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
showResult();
}
});
}
public void showResult() {
display.getResultLabel().setText("It works");
}
}
And here is small helper class:
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.HandlerManager;
import com.google.gwt.event.shared.HandlerRegistration;
public class MockButton implements HasClickHandlers {
private HandlerManager handlerManager = new HandlerManager(this);
public void click() {
handlerManager.fireEvent(new ClickEvent() {
});
}
#Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
return handlerManager.addHandler(ClickEvent.getType(), handler);
}
#Override
public void fireEvent(GwtEvent<?> event) {
handlerManager.fireEvent(event);
}
}
It would make sense to call presenter.showResult() in 'when' section instead of button.click(), however as you can see mocking of event circulation is also possible.
Google GIN might be very useful, as it allows to bind different instances depending on runtime/test context. On non-GWTTestCase presenter test GIN can be replaced with Guice.
The com.google.gwt.junit.GWTMockUtilities might be also very useful.

We're happily using Gwt-test-utils for our GWT project.
Mocking RPC calls with mockito is really easy :
First you declare your mocked service in your test :
#Mock
private ServiceAsync service;
then when you want to mock a successful callback :
doSuccessCallback(result).when(service).myMethod(eq("argument"), any(AsyncCallback.class));
More on that : http://code.google.com/p/gwt-test-utils/wiki/MockingRpcServices

Related

instantiate object from derived class with constructor that takes super argument

Maybe what I am trying to do is not worthwhile, it sure feels that way after spending many days on it.
I have A Base Class shown here:
package jimmy.kilmer.com;
import java.awt.Color;
import jarPackageImports.AI;
import jarPackageImports.MovementAction;
import jarPackageImports.Info;
import jarPackageImports.PlayerAction;
public class GameAI extends AI {
public gameAI(Info info) {
super(info);
setJerseyNumber(32);
}
public Color getColor() {
return Color.RED;
}
public String getName() {
return "Usain Bolt";
}
public PlayerAction update() {
// TODO game movement actions
// all available methods not listed here...
info.getVelocity();
info.getX();
info.getY();
MovementAction steeringBehavior = null;
return steeringBehavior;
}
//basically used for testing setup
public int[][] populateAllPossibleNodes() {
int[][] allPossibleNodes = new int[screenWidth/20][screenHeight/20];
return allPossibleNodes;
}
}
I have been given a jar, that sets up the game environment. It uses reflection for the setup. I am not familiar with reflection, unfortunately, as I am more beginner level.
I have read a lot about TDD, and am convinced that can help me stay orderly, and code in a disciplined way. I have some say that TDD is not really useful for Game development, which the arguments may be true, in regard to making an "enjoyable game." But, from a purely coding standpoint, I remain steadfast in my believe that TDD is the way to go. But, that remains to be seen, since it is still theoretical. I would like to try it.
I have installed Junit 5, and have done many tutorials, but it's all pretty basic examples. My particular test case uses reflection, super classes, derived classes, dynamic data. My head is spinning.
My goal is just to get setup such that I can start doing some Test driven development.
Here is my Junit test class:
package jimmy.kilmer.com;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import jarPackageImports.Info;
class GameAITest {
private GameAITest AIObject;
private jarPackageImports.Info info;
#BeforeEach
void setUp() throws Exception {
AIObject = new GameAITest(info);
#AfterEach
void tearDown() throws Exception {
}
#Test
void testPopulateAllPossibleNodes() {
// 1. given/arrange
int[][] array1 = new int[80][65];
// 2. when/act
int[][] array2 = AIObject.populateAllPossibleNodes();
// 3. then/assert
assertArrayEquals(array1, array2);
}
}
That is my best stab so far, but it still get a compile error. Specifically:
java.lang.NullPointerException:Cannot invoke "jarPackageImports.Info.getScene()" because "this.info" is null
In summation:
maybe everything I am trying is rubbish?
Do I need to use dynamic junit testing? I would have to read up on that.
Do I need to mock (use Mockito?) to instantiate an object to test? I would need to read up on that as well.
Is it possible to instantiate an object from GameAI? Do I need to/how would I use relection to do that? class.getConstructors()? And, I would have to read up on that.
thanks in advance.

JUnit5 - How to get test result in AfterTestExecutionCallback

I write JUnit5 Extension. But I cannot find way how to obtain test result.
Extension looks like this:
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.TestExtensionContext;
public class TestResultExtension implements AfterTestExecutionCallback {
#Override
public void afterTestExecution(TestExtensionContext context) throws Exception {
//How to get test result? SUCCESS/FAILED
}
}
Any hints how to obtain test result?
This work for me:
public class RunnerExtension implements AfterTestExecutionCallback {
#Override
public void afterTestExecution(ExtensionContext context) throws Exception {
Boolean testResult = context.getExecutionException().isPresent();
System.out.println(testResult); //false - SUCCESS, true - FAILED
}
}
#ExtendWith(RunnerExtension.class)
public abstract class Tests {
}
As other answers point out, JUnit communicates failed tests with exceptions, so an AfterTestExecutionCallback can be used to gleam what happened. Note that this is error prone as extension running later might still fail the test.
Another way to do that is to register a custom TestExecutionListener. Both of these approaches are a little roundabout, though. There is an issue that tracks a specific extension point for reacting to test results, which would likely be the most straight-forward answer to your question. If you can provide a specific use case, it would be great if you could head over to #542 and leave a comment describing it.
You can use SummaryGeneratingListener from org.junit.platform.launcher.listeners
It contains MutableTestExecutionSummary field, which implements TestExecutionSummary interface, and this way you can obtain info about containers, tests, time, failures etc.
You can create custom listener, for example:
Create class that extends SummaryGeneratingListener
public class ResultAnalyzer extends SummaryGeneratingListener {
#Override
public void testPlanExecutionFinished(TestPlan testPlan) {
//This method is invoked after all tests in all containers is finished
super.testPlanExecutionFinished(testPlan);
analyzeResult();
}
private void analyzeResult() {
var summary = getSummary();
var failures = summary.getFailures();
//Do something
}
}
Register listener by creating file
src\main\resources\META-INF\services\org.junit.platform.launcher.TestExecutionListener
and specify your implementation in it
path.to.class.ResultAnalyzer
Enable auto-detection of extensions, set parameter
-Djunit.jupiter.extensions.autodetection.enabled=true
And that's it!
Docs
https://junit.org/junit5/docs/5.0.0/api/org/junit/platform/launcher/listeners/SummaryGeneratingListener.html
https://junit.org/junit5/docs/5.0.0/api/org/junit/platform/launcher/listeners/TestExecutionSummary.html
https://junit.org/junit5/docs/current/user-guide/#extensions-registration-automatic
I have only this solution:
String testResult = context.getTestException().isPresent() ? "FAILED" : "OK";
It seems that it works well. But I am not sure if it will work correctly in all situations.
Fails in JUnit are propagated with exceptions. There are several exceptions, which indicate various types of errors.
So an exception in TestExtensionContext#getTestException() indicates an error. The method can't manipulate actual test results, so depending on your use case you might want to implement TestExecutionExceptionHandler, which allows you to swallow exceptions, thus changing whether a test succeeded or not.
You're almost there.
To implement a test execution callback and get the test result for logging (or generating a report) you can do the following:
import org.junit.jupiter.api.extension.AfterTestExecutionCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
public class TestResultExtension implements AfterTestExecutionCallback
{
#Override
public void afterTestExecution(ExtensionContext context) throws Exception
{
// check the context for an exception
Boolean passed = context.getExecutionException().isEmpty();
// if there isn't, the test passed
String result = passed ? "PASSED" : "FAILED";
// now that you have the result, you can do whatever you want
System.out.println("Test Result: " + context.getDisplayName() + " " + result);
}
}
And then you just add the TestResultExtension using the #ExtendWith() annotation for your test cases:
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import static org.junit.jupiter.api.Assertions.assertTrue;
#ExtendWith(TestResultExtension.class)
public class SanityTest
{
#Test
public void testSanity()
{
assertTrue(true);
}
#Test
public void testInsanity()
{
assertTrue(false);
}
}
It's a good idea to extend a base test that includes the extension
import org.junit.jupiter.api.extension.ExtendWith;
#ExtendWith(TestResultExtension.class)
public class BaseTest
{}
And then you don't need to include the annotation in every test:
public class SanityTest extends BaseTest
{ //... }

Java Unit testing path matching

I am trying to understand Unit testing and how the correct classes are being fetched on test time,
I'm having a hard time understanding exactly what is going on behind the scenes and how safe/correct my usages for this are.
This is a very simple example of what i am trying to do, i wrote it here inline so it probably contains some errors, please try to ignore them, as stupid as they may be.
A very simple project directory:
ba/src/main/java/utils/BaUtils.java
ba/test/main/java/utils/BaUtilsTest.java
notBa/src/main/java/im/BaObj.java
BaUtils.java code:
package com.ba.utils;
import notBa.im.BaObj;
public class BaUtils{
public String doSomething(BaObj obj){
obj.doSomething();
}
}
I would like to test BaUtils wihtout actually calling doSomething, and i can't change anything on BaObj class or notBa package. I know that i can (by 'can' i mean it will work) add a new java file to 'ba' project (ba/test/java/notBa/main/java/im/BaObj.java) that will have the same package as the original BaObj, and at runtime the test will import this one instead of the real one, so BaUtils code is tested but BaObj code is not excecuted.
that should look something like like :
package notBa.im.Baobj
public class BaObj{
public void doSomething(){
System.out.println("Did something");
}
}
My questions are (And thank you for reaching this far):
How does this work (Reading references would be great).
Is this kind of test building considered 'good' or 'safe' ?
Thanks!
The solution is to use a mocking framework (I for myself like Mockito).
The test would look like this:
class BlaUtilTes{
#Rule
public MockitoRule mockitoRule = MockitoJUnit.rule();
#Mock
Blaobj blaobj;
#Test
public void doSomething_WithMockedBlaobj_callsDosomethingOnBlaobj(){
// arrange
BlaUtil blaUtil= new BlaUtil();
// act
blaUtil.doSomething(blaobj);
// assert
Mockito.verify(blaobj).doSomething();
}
}
find more information here http://www.vogella.com/tutorials/Mockito/article.html#testing-with-mock-objects
Your BaUtilsTest class should look like this.. I have used mockito for for mocking external dependencies. Also I changed the method return type to String for easy understanding.
#RunWith(MockitoJUnitRunner.class)
class BaUtilsTest {
BaUtils util;
#Mock
BaObj mockBaObj;
#Before
public void setup() {
util = new BaUtils();
}
#Test
public void testDoSomething() {
Mockito.when(mockBaObj.doSomething()).thenReturn("did the work using mock");
String result = util.doSomething(mockBaObj);
Assert.assertEquals("did the work using mock", result);
}
}

How to use JUnit4TestAdapter with objects

I am trying to write a test suite using JUnit4 by relying on JUnit4TestAdapter. Having a look at the code of this class I saw that it only works with a Class as input. I would like to build a test class and set a parameter on it before running it with my TestSuite. Unfortunately, Junit4TestAdapter is building the test by using reflection (not 100% sure about the mechanism behind it), which means that I cannot change my test class on runtime.
Has anybody done anything similar before? Is there any possible workaround to this issue? Thanks for your help!
public class SimpleTest {
#Test
public void testBasic() {
TemplateTester tester = new TemplateTester();
ActionIconsTest test = new ActionIconsTest();
test.setParameter("New Param Value");
tester.addTests(test);
tester.run();
}
}
/////
public class TemplateTester {
private TestSuite suite;
public TemplateTester() {
suite = new TestSuite();
}
public void addTests(TemplateTest... tests) {
for (TemplateTest test : tests) {
suite.addTest(new JUnit4TestAdapter(test.getClass()));
}
}
public void run() {
suite.run(new TestResult());
}
}
/////
public interface TemplateTest {
}
/////
public class ActionIconsTest extends BaseTestStrategy implements TemplateTest {
#Test
public void icons() {
//Test logic here
}
public void navigateToTestPage() {
//Here I need the parameter
}
}
/////
public abstract class BaseTestStrategy {
protected String parameter;
#Before
public void init() {
navigateToTestPage();
}
public abstract void navigateToTestPage();
public void setParameter(String parameter) {
this.parameter = parameter;
}
}
I am trying to test a web application with Selenium. The way I want to test is by splitting the functionality, e.g., I want to test the available icons (ActionIconsTest), then I'd like to test other parts like buttons, etc.
The idea behind this is to have a better categorization of the functionality available in certain screen. This is quite coupled with the way we are currently developing our web app.
With this in mind, TemplateTest is just an interface implemented by the different kind of tests (ActionIconTest, ButtonTest, etc) available in my system.
TemplateTester is a Junit suite test with all the different tests that implement the interface TemplateTest.
The reason for this question is because I was trying to implement a Strategy pattern and then realized of the inconvenient of passing a class to Junit4TestAdapter in runtime.
Well, taking in account that JUNIT needs your tester's Class object as an object factory (so he can create several instances of your tester), I can only suggest you pass parameters to your tester through System Properties.
Moreover, it's the recommended way of passing parameters: http://junit.org/faq.html#running_7

Check if method was called on EasyMock

Using EasyMock 3.2. In order to unit test an UI, I have to mock some dependencies. One of them is Page. Base class for UI tests looks like this:
abstract class AbstractUiTest {
#Before
public function setUpUiDependencies() {
Page page = createNiceMock(Page.class);
Ui.setCurrentPage(page);
}
}
Most of the time I don't use the page explicity, it's just there not to throw NullPointerException when e.g. Ui calls getPage().setTitle("sth") etc.
However, in a few tests I want to explicity check if something has happend with the page, e.g.:
public class SomeTest extends AbstractUiTest {
#Test
public void testNotification() {
// do something with UI that should cause notification
assertNotificationHasBeenShown();
}
private void assertNotificationHasBeenShown() {
Page page = Ui.getCurrentPage(); // this is my nice mock
// HERE: verify somehow, that page.showNotification() has been called
}
}
How to implement the assertion method? I would really want to implement it without recording behavior to the page, replaying and verifying it. My problem is a bit more complicated, but you should get the point.
EDIT: I think that perhaps this is not really needed, since simply using replay and verify should check that the expected methods were actually called. But you said you want to do this without replaying and verifying. Can you explain why you have that requirement?
I think that you can use andAnswer and an IAnswer. You don't mention what the return value of page.showNotification() is. Assuming it returns a String, you could do this:
import static org.easymock.EasyMock.expect;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
#Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
expect(page.showNotification()).andAnswer(new IAnswer<String>() {
#Override
public String answer() {
showNotificationCalled.set(true);
return "";
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
If showNotification returns void, I believe you would need to do this:
import static org.easymock.EasyMock.expectLastCall;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.atomic.AtomicBoolean;
import org.easymock.IAnswer;
import org.junit.Ignore;
import org.junit.Test;
public class SomeTest extends AbstractUiTest {
#Test
public void shouldCallShowNotification() {
final AtomicBoolean showNotificationCalled = new AtomicBoolean();
page.showNotification();
expectLastCall().andAnswer(new IAnswer<Void>() {
#Override
public Void answer() {
showNotificationCalled.set(true);
return null;
}
});
replay(page);
Ui.getCurrentPage();
verify(page);
assertTrue("showNotification not called", showNotificationCalled.get());
}
}
Note: I've used an AtomicBoolean to record whether the method was called. You could also use a boolean array of a single element, or your own mutable object. I used AtomicBoolean not for its concurrency properties, but simply because it is a handy mutable boolean object that is already present in the Java standard libraries.
The other thing that I have done to verify that a method was being called is to not use a mock at all, but to create an instance of Page as an anonymous inner class and override the showNotification method, and record somewhere that the call occurred.
Use a nice mock in the tests where you don't care what happens to page and a normal mock in those tests where you want to test something explicit - and use expect, verify etc. I.e. have two variables in your setup method: nicePage (acts as a stub) and mockPage (acts as a mock)

Categories