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 URLhttp://sally-api.dev/api/users/sign_in
with a body including some JSON. - You are firing a
GET
request to the URLhttp://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:
- 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. - Change your code to trigger a
POST
instead of aGET
- 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.