0

I tried to create unit test for my project. Inside my unit test class I have two methods testCalculate() and testLogin(). Method testCalculate() running fine, meaning that test passed and I got correct testing result.

But problem is in testLogin(), I expect that my code will be print something inside the listener, but it never printed.Meaning that I never get this line

System.out.println("Login success ======= " + response.getResponseObject());

My login method that I want to test itself running fine, meaning if I use it inside my real app, it will login successfully and return some datas that I got from server.

Kindly advise what is possible cause that make my listener is not working in unit test. Really appreciate for any kind help.

@RunWith(RobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class LoginManagerTest {

private static final String TAG = LoginManagerTest.class.getCanonicalName();
private String usernameStr = "androidtest@gmail.com";
private String passwordStr = "********";
private LoginManager loginManager;

@Test
public void testLogin() throws Exception {
    ResponseHandlerListener<String> listener = new ResponseHandlerListener<String>() {
        @Override
        public void onReceive(AxonResponse<String> response) {
            System.out.println("Login success ======= " + response.getResponseObject());
            String loginSuccess = Constants.LOGIN_SUCCESS;
            assertEquals(TAG, loginSuccess, response.getResponseObject());
        }
    };

    Context context = Robolectric.getShadowApplication().getApplicationContext();
    loginManager = new LoginManager(context);
    loginManager.login(usernameStr, passwordStr, null, listener);

}

@Test
public void testCalculate() throws Exception {
    Context context = Robolectric.getShadowApplication().getApplicationContext();
    loginManager = new LoginManager(context);
    int num = 5;
    int sum = loginManager.calculate(num);
    System.out.println("sum = " + sum);
    assertEquals(10, sum);
}

}

Vierda Mila Nartila
  • 613
  • 1
  • 8
  • 27

2 Answers2

2

I had the same issue. I solved by using Robolectric.flushForegroundThreadScheduler(). This will run queued tasks that is on forground thread.

It's going to be like this:

@Test
public void testLogin() throws Exception {
    ResponseHandlerListener<String> listener = new ResponseHandlerListener<String>() {
        @Override
        public void onReceive(AxonResponse<String> response) {
            System.out.println("Login success ======= " + response.getResponseObject());
            String loginSuccess = Constants.LOGIN_SUCCESS;
            assertEquals(TAG, loginSuccess, response.getResponseObject());
        }
    };

    Context context = Robolectric.getShadowApplication().getApplicationContext();
    loginManager = new LoginManager(context);
    loginManager.login(usernameStr, passwordStr, null, listener);
    ThreadSleep(500); //Wait for login process to be executed
    Robolectric.flushForegroundThreadScheduler(); // this will run all the pending queue on Main Thread
}
tomoima525
  • 832
  • 10
  • 13
0

I think the problem is the callback will be called after time, it means run asynchronus, and the test is out of time with other (main) thread. I have no experience about Robolectric test, but a little bit about AndroidTestSuite. So, I suggest you need some waitting time before the listener callback is called. Here is the sample and the other idea. Hope that help.

Update:

Try the below idea (Not tested):

private Object lock = new Object();
@Test
public void testLogin() throws Exception {
    ResponseHandlerListener<String> listener = new ResponseHandlerListener<String>() {
        @Override
        public void onReceive(AxonResponse<String> response) {
            System.out.println("Login success ======= " + response.getResponseObject());
            String loginSuccess = Constants.LOGIN_SUCCESS;
            assertEquals(TAG, loginSuccess, response.getResponseObject());
            synchronized (lock) {
                lock.notifyAll(); // Will wake up lock.wait()
            }
        }
    };
    synchronized (lock) {
        Context context = Robolectric.getShadowApplication().getApplicationContext();
        loginManager = new LoginManager(context);
        loginManager.login(usernameStr, passwordStr, null, listener);
        lock.wait();
    }
}
Community
  • 1
  • 1
NamNH
  • 1,752
  • 1
  • 15
  • 37
  • Hi Nam, thanks for your reply I have tried your suggestion and also tried this solution that mentioned in this thread but still no luck, I'm still not getting anything from my listener --> http://stackoverflow.com/questions/16816600/getting-robolectric-to-work-with-volley – Vierda Mila Nartila Jan 20 '16 at 03:17
  • @VierdaMilaNartila check my updated answer, just the idea, because I have not tested it. Goodluck! – NamNH Jan 20 '16 at 04:36