lundi 25 mai 2015

Non-Mock Android Integration tests

  1. If you are going to suggest that I use mock objects, please do not reply to this post. Just click the back button and move on with your existing un-integrated life.
  2. No hypotheticals. Please don't post a response unless you have tested your theory first.
  3. If you're concerned about the wrappers I have built causing the issue then please respond with a generic example of integration testing for asynchronous methods that does work. -Thanks

In iOS I can make an integration test like this

let expectation = expectationWithDescription("Sign in");

var email: String = "asdf@asdf.co";
var password: String = "Free Milk Lane";

PersonAPI.signIn(email, password: password, done:{(response: APIResponse)->Void in

    XCTAssertTrue(response.success == true);

    if(response.success == true)
    {
        var user: Person! = response.data as! Person!;

        XCTAssertTrue(user != nil);

        if(user != nil)
        {
            XCTAssertEqual("Mr", user.getFirstName());
            XCTAssertEqual("Tester", user.getLastName());
            XCTAssertEqual(1, user.getID());
        }
    }

    expectation.fulfill();

});

waitForExpectationsWithTimeout(5.0, handler:nil);

But in Android its not so obvious. Right now I am trying to use Roboelectric & Retrofit but it just doesn't want to cooperate. I have tried lots of things and I think the issue is related to how the threads for are pooled. For example the following code will pass but waits 5 seconds no matter what:

// Setup signal to prevent from test ending before all async tasks finish.
final CountDownLatch signal = new CountDownLatch(2);

// call API method for signing up
PersonAPI.signIn(TEST_EMAIL, TEST_INVALID_PASSWORD, new IAPICallback() {
    @Override
    public void done(APIResponse response) {
    // check response for errors
    Assert.assertFalse(response.getMessage(), response.isSuccessful());
    Assert.assertNull("Response data must be 'null'", response.getData());

    // mark async operation is completed
        signal.countDown();
    }
});

// wait until all async operations completed
signal.await(5, TimeUnit.SECONDS);

Robolectric.flushForegroundScheduler();

At this point I'm willing to try anything (except mocking). Change out the retrofit, reoboelectric, whatever.

Thanks again

Aucun commentaire:

Enregistrer un commentaire