The section on GWT testing describes how to verify output of Presenter in Display object, but does not explain how to do the other way around. In other words, I want to check whether Presenter will make a correct request to RPC Service when a user clicks button in Display.
How can I simulate button click in Display? Firing GWT events is not straightforward, as they have protected constructors. Is there a way to do it simply, without subclassing ClickEvent class?
#Before
protected void setUp() {
mockRpcService = mock(NegotiationServiceAsync.class);
eventBus = new HandlerManager(null);
mockDisplay = mock(NegotiationPresenter.Display.class);
negotiationPresenter = new NegotiationPresenter(mockRpcService,
eventBus, mockDisplay);
}
#Test
private void testSth() {
when(mockDisplay.getSuppliersEmails()).thenReturn("address#domain.com");
when(mockDisplay.getTaskDescription()).thenReturn("This is the task to do");
// This does not work
mockDisplay.getSubmitButton().fireEvent(new ClickEvent());
verify(mockRpcService).startTask(any(NegotiationRequest.class), any(AsyncCallback.class));
}
When you use MVP you normally test methods in the presenter injecting a mocked implementation of the view, so in your test the display does nothing, just offers stub methods to the presenter.
In the other hand, your real display implementation should delegate all actions to the presenter.
The way to test the behavior of your presenter when a user clicks on the submit button is calling the method in the presenter, something like this:
#Test
private void testSth() {
when(mockDisplay.getSuppliersEmails()).thenReturn("address#domain.com");
when(mockDisplay.getTaskDescription()).thenReturn("This is the task to do");
negotiationPresenter.onSubmit();
verify(mockRpcService).startTask(any(NegotiationRequest.class),
any(AsyncCallback.class));
}
A very different case is if you wanted to test your code using GWTTestCase so as you could use real view implementations, but in this case your tests would last a long, loosing one of the main goals of using MVP, which is, to decouple the view to test the main app code which is supposed to be in Presenters and classes which can be run in the JVM.
Related
I am making an android game with the libGDX Java game library. I would like to test my code but not quite sure how to go about it. I have set up testing and run sample tests like.
public class UnitTestExample {
#Test
public void oneEqualsOne() {
assertEquals(1, 1);
}
}
Now how do I test a function like
public void addListenerToExitButton(){
buttonExit.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {Gdx.app.exit();
}
});
}
This function adds a LibGDX event to a button called buttonExit (In this case, the event is to exit the game.)
I use JMockIt for unit testing for my LibGdx projects and it works like a charm.
For your case, I assume the method you want to test is in a screen class, in other words, that is the class you are testing. Therefore you need to mock up all dependencies of this class and then instantiate it.Again I assume that button instance would be a private member of that class. So, under normal circumstances, you can not access it from your test code. JMockit can help you with that:
TextButton buttonToTest = (TextButton) Deencapsulation.getField(yourScreenUnderTest, "yourButtonName");
buttonToTest.toggle();
Above code will get the button and emulate click event on it. In this context, Gdx.app is a dependency and you already have mocked it up. What it means that, when your button is clicked, your mock instance will expect and exit call without any parameters. So, if you add this to your expectations, you are done.
Simple and elegant =]
I'm managing the History in my project via Places.
What I do is this:
implement PlaceRequestHandler on top level (for example AppController),
register it -> eventBus.addHandler(PlaceRequestEvent.getType(), this);
implement method "onPlaceRequest" ,where i do project navigation.
I'm using GWT presenter and every presenter in my project overrides the onPlaceRequest method.
Why do I need this, when every request is handled from the top level "onPlaceRequest" method?
I will give an example:
public class AppController implements Presenter, PlaceRequestHandler
...........
public void bind()
{
eventBus.addHandler(PlaceRequestEvent.getType(), this);
...
}
public void onPlaceRequest(PlaceRequestEvent event)
{
// here is the project navigation tree
}
and let's take one presenter
public class SomePresenter extends Presenter<SomePresenter.Display>
{
... here some methods are overriden and
#Override
protected void onPlaceRequest(PlaceRequest request)
{
// what should I do here?
}
}
What is the idea, and how I'm supposed to use it?
Instead of making all of your presenters extend PlaceRequestHandler and managing those events yourself, you can attach a PlaceHistoryHandler and a PlaceController to your event bus. Together, they manage the browser's history and your places for you. When you ask your PlaceController to goTo() a different place, it will stop your current activity and use a mapping of places to activities (your presenters) to choose which one to start next.
To use this technique, you need to have your presenters extend AbstractActivity. Try following through Google's tutorial about it in GWT's documentation called GWT Development with Activities and Places.
What is the simplest way to make sure the listener's update has even been called ?
Update: I am testing the Listener (not the Subject) and once update is called, the test pass.
d.addServiceComponentChangeListener(new ServiceComponentChangeListener() {
//In the Unittest, I want to make sure this has been called
public void notifyChange(ServiceComponentChangeEvent event) {
System.out.println("#notifyChange");
}
});
Even if the listener does not implement an interface, you can still create a mock for it using something like Mockito. Using runtime code insertion, inspection of the class to be mocked, and purple pixie dust, it can impersonate other classes. At my company most unit tests use either Mockito (the newer ones) or EasyMock (the older ones) so we're sure we're testing JUST the one class.
I question your statement "Update: I am testing the Listener (not the Subject)", though. If your test is verifying the listener gets called, you're testing the thing that's supposed to call the listener, not listener itself. So which is it?
If the listener implements the interface you can make a mock class that implements the listener. Then you can design this mock to fit your testing. If it does not implement an interface, as long as the listeners class is not final, you could extend it.
I would test it by replace the call System.out or whatever that section should really do with an interface that be later mocked and use behavior verification to make sure it was called. So...
public class d
{
private MessageDisplayer m_UserDisplay;
public d()
{
m_UserDisplay = new DisplaySystemOut()
}
public d(MessageDisplayer AllowsSensing)
{
m_UserDisplay = AllowsSensing;
}
//blah blah blah....
d.addServiceComponentChangeListener(new ServiceComponentChangeListener()
{
public void notifyChange(ServiceComponentChangeEvent event) {
m_UserDisplay.DisplayMessage("#notifyChange");
}
});
}
Now you can mock MessageDisplayer in your test and make sure it is called and that the parameter was equal to "#notifyChange"
I am thinking about implementing a user interface according to the MVP pattern using GWT, but have doubts about how to proceed.
These are (some of) my goals:
the presenter knows nothing about the UI technology (i.e. uses nothing from com.google.*)
the view knows nothing about the presenter (not sure yet if I'd like it to be model-agnostic, yet)
the model knows nothing of the view or the presenter (...obviously)
I would place an interface between the view and the presenter and use the Observer pattern to decouple the two: the view generates events and the presenter gets notified.
What confuses me is that java.util.Observer and java.util.Observable are not supported in GWT. This suggests that what I'm doing is not the recommended way to do it, as far as GWT is concerned, which leads me to my questions: what is the recommended way to implement MVP using GWT, specifically with the above goals in mind? How would you do it?
Program Structure
This is how I did it. The Eventbus lets presenters (extending the abstract class Subscriber) subscribe to events belonging to different modules in my app. Each module corresponds to a component in my system, and each module has an event type, a presenter, a handler, a view and a model.
A presenter subscribing to all the events of type CONSOLE will receive all the events triggered from that module. For a more fine-grained approach you can always let presenters subscribe to specific events, such as NewLineAddedEvent or something like that, but for me I found that dealing with it on a module level was good enough.
If you want you could make the call to the presenter's rescue methods asynchronous, but so far I've found little need to do so myself. I suppose it depends on what your exact needs are. This is my EventBus:
public class EventBus implements EventHandler
{
private final static EventBus INSTANCE = new EventBus();
private HashMap<Module, ArrayList<Subscriber>> subscribers;
private EventBus()
{
subscribers = new HashMap<Module, ArrayList<Subscriber>>();
}
public static EventBus get() { return INSTANCE; }
public void fire(ScEvent event)
{
if (subscribers.containsKey(event.getKey()))
for (Subscriber s : subscribers.get(event.getKey()))
s.rescue(event);
}
public void subscribe(Subscriber subscriber, Module[] keys)
{
for (Module m : keys)
subscribe(subscriber, m);
}
public void subscribe(Subscriber subscriber, Module key)
{
if (subscribers.containsKey(key))
subscribers.get(key).add(subscriber);
else
{
ArrayList<Subscriber> subs = new ArrayList<Subscriber>();
subs.add(subscriber);
subscribers.put(key, subs);
}
}
public void unsubscribe(Subscriber subscriber, Module key)
{
if (subscribers.containsKey(key))
subscribers.get(key).remove(subscriber);
}
}
Handlers are attached to components, and are responsible for transforming native GWT events into events specialised for my system. The handler below deals with ClickEvents simply by wrapping them in a customised event and firing them on the EventBus for the subscribers to deal with. In some cases it makes sense for the handlers to perform extra checks before firing the event, or sometimes even before deciding weather or not to send the event. The action in the handler is given when the handler is added to the graphical component.
public class AppHandler extends ScHandler
{
public AppHandler(Action action) { super(action); }
#Override
public void onClick(ClickEvent event)
{
EventBus.get().fire(new AppEvent(action));
}
Action is an enumeration expressing possible ways of data manipulation in my system. Each event is initialised with an Action. The action is used by presenters to determine how to update their view. An event with the action ADD might make a presenter add a new button to a menu, or a new row to a grid.
public enum Action
{
ADD,
REMOVE,
OPEN,
CLOSE,
SAVE,
DISPLAY,
UPDATE
}
The event that's get fired by the handler looks a bit like this. Notice how the event defines an interface for it's consumers, which will assure that you don't forget to implement the correct rescue methods.
public class AppEvent extends ScEvent {
public interface AppEventConsumer
{
void rescue(AppEvent e);
}
private static final Module KEY = Module.APP;
private Action action;
public AppEvent(Action action) { this.action = action; }
The presenter subscribes to events belonging to diffrent modules, and then rescues them when they're fired. I also let each presenter define an interface for it's view, which means that the presenter won't ever have to know anything about the actual graphcal components.
public class AppPresenter extends Subscriber implements AppEventConsumer,
ConsoleEventConsumer
{
public interface Display
{
public void openDrawer(String text);
public void closeDrawer();
}
private Display display;
public AppPresenter(Display display)
{
this.display = display;
EventBus.get().subscribe(this, new Module[]{Module.APP, Module.CONSOLE});
}
#Override
public void rescue(ScEvent e)
{
if (e instanceof AppEvent)
rescue((AppEvent) e);
else if (e instanceof ConsoleEvent)
rescue((ConsoleEvent) e);
}
}
Each view is given an instance of a HandlerFactory that is responsible for creating the correct type of handler for each view. Each factory is instantiated with a Module, that it uses to create handlers of the correct type.
public ScHandler create(Action action)
{
switch (module)
{
case CONSOLE :
return new ConsoleHandler(action);
The view is now free to add handlers of different kind to it's components without having to know about the exact implementation details. In this example, all the view needs to know is that the addButton button should be linked to some behaviour corresponding to the action ADD. What this behaviour is will be decided by the presenters that catch the event.
public class AppView implements Display
public AppView(HandlerFactory factory)
{
ToolStripButton addButton = new ToolStripButton();
addButton.addClickHandler(factory.create(Action.ADD));
/* More interfacy stuff */
}
public void openDrawer(String text) { /*Some implementation*/ }
public void closeDrawer() { /*Some implementation*/ }
Example
Consider a simplified Eclipse where you have a class hierarchy to the left, a text area for code on the right, and a menu bar on top. These three would be three different views with three different presenters and therefore they'd make up three different modules. Now, it's entirely possible that the text area will need to change in accordance to changes in the class hierarchy, and therefore it makes sense for the text area presenter to subscribe not only to events being fired from within the text area, but also to events being fired from the class hierarchy. I can imagine something like this (for each module there will be a set of classes - one handler, one event type, one presenter, one model and one view):
public enum Module
{
MENU,
TEXT_AREA,
CLASS_HIERARCHY
}
Now consider we want our views to update properly upon deletion of a class file from the hierarchy view. This should result in the following changes to the gui:
The class file should be removed from the class hierarchy
If the class file is opened, and therefore visible in the text area, it should be closed.
Two presenters, the one controlling the tree view and the one controlling the text view, would both subscribe to events fired from the CLASS_HIERARCHY module. If the action of the event is REMOVE, both preseneters could take the appropriate action, as described above. The presenter controlling the hierarchy would presumably also send a message to the server, making sure that the deleted file was actually deleted. This set-up allows modules to react to events in other modules simply by listening to events fired from the event bus. There is very little coupling going on, and swapping out views, presenters or handlers is completely painless.
I achieved something on these lines for our project. I wanted a event-driven mechanism (think of PropertyChangeSupport and PropertyChangeListener of standard jdk lib) which were missing. I believe there is an extension module and decided to go ahead with my own. You can google it for propertychangesupport gwt and use it or go with my approach.
My approach involved logic centred around MessageHandler and GWTEvent. These serve the same purpose as that of PropertyChangeListener and PropertyChangeEvent respectively. I had to customize them for reasons explained later. My design involved a MessageExchange, MessageSender and MessageListener. The exchange acts as a broadcast service dispatching all events to all listeners. Each sender fires events that are listened by the Exchange and the exchange the fires the events again. Each listener listens to the exchange and can decide for themselves (to process or not to process) based on the event.
Unfortunately MessageHandlers in GWT suffer from a problem: "While a event is being consumed, no new handlers can be hooked". Reason given in the GWT form: The backing iterator holding the handlers cannot be concurrently modified by another thread. I had to rewrite custom implementation of the GWT classes. That is the basic idea.
I would've posted the code, but I am on my way to airport right now, will try to post the code as soon as I can make time.
Edit1:
Not yet able to get the actual code, got hold of some power-point slides I was working on for design documentation and created a blog entry.
Posting a link to my blog article: GXT-GWT App
Edit2:
Finally some code soup.
Posting 1
Posting 2
Posting 3
have a look at: http://www.gwtproject.org/javadoc/latest/com/google/gwt/event/shared/EventBus.html
(which outdates http://www.gwtproject.org/javadoc/latest/com/google/web/bindery/event/shared/EventBus.html)
It should run fine with GWT as I'll try right now myself.
I am writing a TotalCommander-like application. I have a separate component for file list, and a model for it. Model support listeners and issues a notification for events like CurrentDirChanged etc. in following manner:
private void fireCurrentDirectoryChanged(final IFile dir) {
if (SwingUtilities.isEventDispatchThread())
for (FileTableEventsListener listener : tableListeners)
listener.currentDirectoryChanged(dir);
else {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
for (FileTableEventsListener listener : tableListeners)
listener.currentDirectoryChanged(dir);
}
});
}
}
I've written a simple test for this:
#Test
public void testEvents() throws IOException {
IFile testDir = mockDirectoryStructure();
final FileSystemEventsListener listener =
context.mock(FileSystemEventsListener.class);
context.checking(new Expectations() {{
oneOf(listener).currentDirectoryChanged(with(any(IFile.class)));
}});
FileTableModel model = new FileTableModel(testDir);
model.switchToInnerDirectory(1);
}
This does not work, because there is no EventDispatchThread. Is there any way to unit test this inside the headless build?
unit-testing java swing jmock
Note, generally speaking unit testing on UI stuff is always difficult because you have to mock out a lot of stuff which is just not available.
Therefore the main aim when developing applications (of any type) is always to try to separate UI stuff from the main application logic as much as possible. Having strong dependencies here, make unit testing really hard, a nightmare basically. This is usually leveraged by using patterns like a MVC kind of approach, where you mainly test your controller classes and your view classes do nothing than constructing the UI and delegating their actions and events to the controllers. This separates responsibilities and makes testing easier.
Moreover you shouldn't necessarily test things which are provided by the framework already such as testing whether events are correctly fired. You should just test the logic you're writing by yourself.
Look this:
FEST is a collection of libraries, released under the Apache 2.0 license, whose mission is to simplify software testing. It is composed of various modules, which can be used with TestNG or JUnit...
Check the uispec4j project. That's what I use to test my UIs.
www.uispec4j.org
I think the problem with testing is revealing a problem with the code. It shouldn't really be the model's job to decide whether it's running in the dispatch thread, that's too many responsibilities. It should just do its notification job and let a calling component decide whether to call it directly or to invokeLater. That component should be in the part of the code that knows about Swing threads. This component should only know about files and such.
I've only been working with jMock for two days... so please excuse me if there is a more elegant solution. :)
It seems like your FileTableModel depends on SwingUtilities... have you considered mocking the SwingUtilities that you use? One way that smells like a hack but would solve the problem would be to create an interface, say ISwingUtilities, and implement a dummy class MySwingUtilities that simply forwards to the real SwingUtilities. And then in your test case you can mock up the interface and return true for isEventDispatchThread.
#Test
public void testEventsNow() throws IOException {
IFile testDir = mockDirectoryStructure();
final ISwingUtilities swingUtils = context.mock( ISwingUtilities.class );
final FileSystemEventsListener listener =
context.mock(FileSystemEventsListener.class);
context.checking(new Expectations()
{{
oneOf( swingUtils ).isEventDispatchThread();
will( returnValue( true ) );
oneOf(listener).currentDirectoryChanged(with(any(IFile.class)));
}});
FileTableModel model = new FileTableModel(testDir);
model.setSwingUtilities( swingUtils ); // or use constructor injection if you prefer
model.switchToInnerDirectory(1);
}