I’m working on an iOS app whose primary purpose is communication with a set of remote webservices. For integration testing, I’d like to be able to run my app against some sort of fake webservices that have a predictable result.
So far I’ve seen two suggestions:
- Create a webserver that serves static results to the client (for example here).
- Implement different webservice communication code, that based on a compile time flag would call either webservices or code that would load responses from a local file (example and another one).
I’m curious what the community thinks about each of this approaches and whether there are any tools out there to support this workflow.
Update: Let me provide a specific example then. I have a login form that takes a username and password. I would like to check two conditions:
- wronguser@blahblah.com getting login denied and
- rightuser@blahblah.com logging in successfully.
So I need some code to check the username parameter and throw an appropriate response at me. Hopefully that’s all the logic that I need in the “fake webservice”. How do I manage this cleanly?
As far as option 1, I have done this in the past using CocoaHTTPServer and embedding the server directly in an OCUnit test:
https://github.com/robbiehanson/CocoaHTTPServer
I put up the code for using this in a unit test here:
https://github.com/quellish/UnitTestHTTPServer
After all, HTTP is by design just request/response.
Mocking a web service, wether by creating a mock HTTP server or creating a mock web service in code, is going to be about the same amount of work. If you have X code paths to test, you have at least X code paths to handle in your mock.
For option 2, to mock the web service you would not be communicating with the web service, you would be instead be using the mock object which has known responses.
[MyCoolWebService performLogin:username withPassword:password]would become, in your test
[MyMockWebService performLogin:username withPassword:password]The key point being that MyCoolWebService and MyMockWebService implement the same contract (in objective-c, this would be a Protocol). OCMock has plenty of documentation to get you started.
For an integration test though, you should be testing against the real web service, such as a QA/staging environment. What you are actually describing sounds more like functional testing than integration testing.