Mario Dennis
Mario Dennis

Reputation: 3016

Unit Testing Multi thread Api

I am writing a Api that executes HTTP Request on a worker thread then call a method of a Callback-Handler when finish.

public class GriklyClient <E,T>{

private final IHttpRequest<E,T> request;
private final ResponseListener<T> response;


protected GriklyClient (IHttpRequest<E,T> request,ResponseListener<T> response)
{
    this.request = request;
    this.response = response;
}



/**
 * Dispatch a thread to process
 * HTTP Request.
 */
public void execute ()
{
    Runnable thread = new Runnable() 
    {

        public void run() 
        {
            T result = (T) request.execute ();  
            response.response(result);
        }
    };
    new Thread(thread).start();
}//end execute method

}

This is how a call to the ApI looks like:

 Grikly grikly = new Grikly(developerKey);
 grikly.addValidUserCredential(email,password);
 grikly.fetchUser(1, new ResponseListener<User>() {
        public void response(User result) {
            // TODO Auto-generated method stub
            System.out.println(result);
        }
    });

The problem I am having is Unit Testing. The Callback Handler is not being called in my Unit Test thus all my Test always pass even when they should fail.

  private Grikly grikly = new Grikly (developerKey);
  @Test
public void fetchUser ()
{
    grikly.fetchUser(1, new ResponseListener<User>() {

        public void response(User result) {
            Assert.assertNotNull(result);

        }
    });
}//end fetchUser Test

How can I write a Unit test to test this Api?

Upvotes: 2

Views: 102

Answers (1)

DarKeViLzAc
DarKeViLzAc

Reputation: 208

Well, I guess your problem here is because your method fetchUser is an asynchonous method rather than a synchonous one which will not return until it have done its job.

So, the calling of grikly.fetchUser(... will return immediately(so does the test method fetchUser() w/o any sign of failure or success), while the 'lonely' thread you create in GriklyClient will keep running and finish its job by calling the callback method response in your new ResponseListener<User> and of course, nobody cares at that time.

IMO, either a CountdownLatch or a more general ReentrantLock with its Condition buddy can save your day. And tutorials talking about these two tools can be easily found using Google. Good luck with that.

EDIT:
On a second thought, if you wanna test the result that got passed to the callback method, it might be necessary to pass(or publish) it from the new thread you create to the test main thread(by save it to a lock guarded or volatile decorated field) and test it in the @Test annotated method, which in your case is the fetchUser().

Upvotes: 1

Related Questions