Testing a GWTP presenter with asynchronous calls

I use GWTP, adding a contract level to abstract the knowledge between Presenter and View, and I'm pretty happy with the result with GWTP. I am testing my speakers with Mockito.

But over time, I found it difficult to maintain a clean presentation with its tests. There are some refactoring tools that I did to improve this, but I was still not satisfied.

I found the following: My presenters often require an asynchronous call, or even call the object callback method to continue my presenter flow (usually they are nested).

For example:

this.populationManager.populate(new PopulationCallback() { public void onPopulate() { doSomeStufWithTheView(populationManager.get()); } }); 

In my tests, I ended up checking the population () call of the mockinged PopulationManager object. Then create another test for the doSomeStufWithTheView () method.

But I quickly discovered that it was a bad design: any changes or refactoring ended to break a lot of my tests, and made me create from the beginning of the others, even though the presenter’s functionality did not change! Plus, I did not test if the callback was really what I wanted.

So, I tried to use the mockito doAnswer method so as not to disrupt the testing flow of my presenter:

 doAnswer(new Answer(){ public Object answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); ((PopulationCallback)args[0]).onPopulate(); return null; } }).when(this.populationManager).populate(any(PopulationCallback.class)); 

I took into account the code so that it is less verbose (and internally less dependent on the arg position):

 doAnswer(new PopulationCallbackAnswer()) .when(this.populationManager).populate(any(PopulationCallback.class)); 

Therefore, mocking the publicManager, I could still check my host's thread, basically like this:

 @Test public void testSomeStuffAppends() { // Given doAnswer(new PopulationCallbackAnswer()) .when(this.populationManager).populate(any(PopulationCallback.class)); // When this.myPresenter.onReset(); // Then verify(populationManager).populate(any(PopulationCallback.class)); // That was before verify(this.myView).displaySomething(); // Now I can do that. } 

I am wondering if it is good to use the doAnswer method, or if it is a smell of code, and a better design can be used?

Usually my presenters tend to just use other objects (for example, some mediator template) and interact with the view. I have a lead with several hundred (~ 400) lines of code.

Again, is this evidence of poor design, or is it normal for a presenter to be verbose (because he uses other objects)?

Has anyone heard of a project that uses GWTP and validates its presenter cleanly?

Hope I fully explained.

Thanks in advance.

PS: I'm new to Stack Overflow, plus my English is still not enough, if my question needs to be improved, please tell me.

+8
testing mockito gwt gwt-platform
source share
3 answers

You can use ArgumentCaptor :
Check out this post.

+1
source share

If I understand correctly, you are asking about design / architecture.

This should not be considered the answer, these are just my thoughts.

If I executed the code:

  public void loadEmoticonPacks() { executor.execute(new Runnable() { public void run() { pack = loadFromServer(); savePackForUsageAfter(); } }); } 

I usually don’t count on the executor and just check that the methods do the specific work, loading and saving. Thus, the executor here is just a tool to prevent lengthy operations in the user interface stream.

If I have something like:

 accountManager.setListener(this); .... public void onAccountEvent(AccountEvent event) { .... } 

First, I will verify that we are subscribing to events (and unsubscribing from some killings), and I would verify that onAccountEvent expected scripts.

UPD1. Probably, in example 1, it would be better to extract the loadFromServerAndSave method and verify that it is not executed in the user interface thread, and also verify that it does everything as expected.

UPD2. It is better to use a framework such as Guava Bus to handle events.

0
source share

We also use this doAnswer pattern in our host tests, and it usually works fine. One caveat: if you check it this way, you will effectively remove the asynchronous nature of the call, that is, the callback is executed immediately after the server call is initiated.

This can lead to undiscovered race conditions. To test them, you can do this in a two-step process: when the server is called, the response method only saves the callback. Then, when that suits your test, you call sometinh like flush () or onSuccess () in your answer (I would suggest making a utility class for this that can be reused in other circumstances) so that you can control when the callback is for the result is really called.

0
source share

All Articles