luisobo / Nocilla

Testing HTTP requests has never been easier. Nocilla: Stunning HTTP stubbing for iOS and Mac OS X.

Home Page:https://twitter.com/luisobo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Problem stubbing a JSON request with AFNetworking 2

zaid opened this issue · comments

I'm just starting to use Nocilla to stub some of the requests to our JSON API and I keep getting an unexpected request thrown exception.

The exception message shows:

'NocillaUnexpectedRequest', reason: 'An unexpected HTTP request was fired.

Use this snippet to stub the request:
stubRequest(@"GET", @"http://sally-api.dev/api/users/sign_in?email=zaid%40place.ca&password=secret").
withHeaders(@{ @"Accept-Language": @"en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5", @"User-Agent": @"Sally/1.0 (iPhone Simulator; iOS 7.1; Scale/2.00)" });

I am using Specta + Expecta to write the tests and my test looks like the following:

    beforeAll(^{
        [Expecta setAsynchronousTestTimeout: 5];
        [[LSNocilla sharedInstance] start];
    });
    afterEach(^{
        [[LSNocilla sharedInstance] clearStubs];
    });

    afterAll(^{
        [[LSNocilla sharedInstance] stop];
    });

    describe(@"Sign-in", ^{
        context(@"success", ^{
            it(@"should pass the token to the delegate", ^{
                stubRequest(@"GET", @"http://sally-api.dev/api/users/sign_in").
                withHeader(@"Accept", @"application/json").
                withBody(@"{\"email\":\"zaid@place.ca\", \"password\":\"secret\"}").
                andReturn(200).
                withBody(@"api_token");

                [communicator signInWithEmail: @"zaid@place.ca" password: @"secret"];

                expect(communicatorDelegate.apiToken).will.equal(@"api_token");
            });
        });
});

The will keyword will wait for 5 seconds until the request completes.

I'm probably missing something obvious so any help is greatly appreciated.

Hi @zaid and thanks for using Nocilla.

The error that you are seeing is correct. The request that you are triggering is not matching the one that you are stubbing:

  • You are expecting (stubbing) a GET request to the URL http://sally-api.dev/api/users/sign_in with a body including some JSON.
  • You are firing a GET request to the URL http://sally-api.dev/api/users/sign_in?email=zaid%40place.ca&password=secret with no body.

In order for Nocilla to stub the request they have to match, otherwise requests are treated as unexpected and test fail.

You need to either:

  • Update your code to make fire the request that you are expecting
  • Update your expectation to match the actual request that you are firing.

The simplest answer would be to use the suggested snippet that comes with the error to stub the request.

NOW, and this is not related with Nocilla but with API design, here is what I'd do:

  1. I'd make sure that your backend expects a POST request (my guess is that it already does, rails + devise? 😁) for the /api/users/sign_in endpoint.
  2. Change your code to trigger a POST instead of a GET
  3. Change your test to expect a POST as well.

In the semantics of HTTP you should be using POST for actions with side effects like creating a session. If you are positive that your /api/users/sign_in endpoint is side-effect free a GET would be okay and updating the code to not use a body would be the way to go.

I'm gonna close the issue but please, feel free to comment with any other question.

Hi @luisobo,

Thank you for the quick reply and detailed explanation. We are using Rails and Devise 😄 I changed the test to use the snippet from the exception and everything works as expected.

I believe that the sign_in process in our case is side-effect free since nothing gets created / updated and we merely return the auth_token that's already associated with the user (but I'll double check just to be sure).

Thank you for your work on Nocilla.