-
Notifications
You must be signed in to change notification settings - Fork 599
Usage Examples
With the code below, every network request (because you returned YES in the first block) will return a stubbed response containing the data "Hello World!":
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
return YES; // Stub ALL requests without any condition
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) {
// Stub all those requests with "Hello World!" string
NSData* stubData = [@"Hello World!" dataUsingEncoding:NSUTF8StringEncoding];
return [OHHTTPStubsResponse responseWithData:stubData statusCode:200 headers:nil];
}];Note that in practice, it is not recommended to directly
return YESin the first block and thus stub all requests, because third-party frameworks & SDKs (likeCrashlytics, etc) may also send requests and you probably don't want them to receive your own stubbed response (which won't make sense for them anyway).That's why it's preferred to explicitly use a computed condition in this first block, like in the examples below
This is typically useful in your Unit Tests to only stub specific requests targeted to a given host or WebService, for example.
With the code below, only requests to the mywebservice.com host will be stubbed. Requests to any other host will hit the real world:
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
return [request.URL.host isEqualToString:@"mywebservice.com"];
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) {
// Stub it with our "wsresponse.json" stub file
return [OHHTTPStubsResponse responseWithFileAtPath:OHPathForFileInBundle(@"wsresponse.json",nil)
statusCode:200 headers:@{@"Content-Type":@"application/json"}];
}];This example also demonstrate how to easily return the content of a given file in your application bundle. This is useful if you have all your fixtures (stubbed responses for your Unit Tests) in your Xcode project linked with your Unit Test target.
Note: You may even put all your fixtures in a custom bundle (let's call it
Fixtures.bundle) and then use the helper macros to get it:OHPathForFileInBundle(@"wsresponse.json",OHResourceBundle(@"Fixtures")).
Some people also like having their own macro for that, e.g.#define fixture(x) OHPathForFileInBundle(@ #x ".json",OHResourceBundle(@"Fixtures"))so that they can simply usefixture(wsresponse)in their code.
As it is common for a lot of WebServices to use the JSON format in their response body, OHHTTPStubs comes with a convenience method (defined as a category in OHHTTPStubs+JSON.) to build a response from a JSON object.
In practice, this convenience method simply use
NSJSONSerializationto transform theNSDictionaryorNSArrayto JSON, and automatically adds theContent-Type: application/jsonheader if there is noContent-Typeheader defined.
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
return [request.URL.host isEqualToString:@"mywebservice.com"];
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) {
NSDictionary* obj = @{ @"key1": @"value1", @"key2": @[@"value2A", @"value2B"] };
return [OHHTTPStubsResponse responseWithJSONObject:obj statusCode:200 headers:nil];
}];You can simulate a slow network by setting the requestTime and/or responseTime properties of your OHHTTPStubsResponse.
This is useful to check that your user interface does not freeze when you have bad network conditions, and that you have all your activity indicators working while waiting for responses.
You may use the commodity chainable setters responseTime: and requestTime:responseTime: to set those values and easily chain method calls:
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
return [request.URL.host isEqualToString:@"mywebservice.com"];
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) {
return [[OHHTTPStubsResponse responseWithJSONObject:someDict statusCode:200 headers:nil]
requestTime:1.0 responseTime:3.0];
}];OHHTTPStubs will wait requestTime before sending the NSHTTPURLResponse, and then start sending chunks of the stub data regularly during the period of responseTime, to simulate the slow network.
In the end, you will only have the full content of your stub data after requestTime+responseTime (time after which the completion block or connectionDidFinishLoading: delegate method will be called).
Note: You can specify a network speed instead of a
responseTimeby using a negative value. See below.
You may also return a network error for your stub. For example, you can easily simulate an absence of network connection like this:
NSError* notConnectedError = [NSError errorWithDomain:NSURLErrorDomain code:kCFURLErrorNotConnectedToInternet userInfo:nil];
[OHHTTPStubsResponse responseWithError:notConnectedError];OHHTTPStubsResponse.h includes a useful set of macros to build a path to your fixtures easily, like OHPathForFileInBundle, OHPathForFileInDocumentsDir and OHResourceBundle. You are encouraged to use them to build your path more easily.
Especially, they use
[NSBundle bundleForClass:self.class]to reference your app bundle (and not[NSBundle mainBundle]as one may think), so that they still work with OCUnit and XCTestKit when unit-testing your app in the Simulator.
When building the OHHTTPStubsResponse object, you can specify a response time (in seconds) so that the sending of the fake response will be spread over time. This allows you to simulate a slow network for example. (see "Set request and response time")
If you specify a negative value for the responseTime parameter, instead of being interpreted as a time in seconds, it will be interpreted as a download speed in KBytes/s. In that case, the response time will be computed using the length of the response's data to simulate the indicated download speed.
The OHHTTPStubsResponse header defines some constants for standard download speeds:
OHHTTPStubsDownloadSpeedGPRS = -7 = 7 KB/s = 56 kbps
OHHTTPStubsDownloadSpeedEDGE = -16 = 16 KB/s = 128 kbps
OHHTTPStubsDownloadSpeed3G = -400 = 400 KB/s = 3200 kbps
OHHTTPStubsDownloadSpeed3GPlus = -900 = 900 KB/s = 7200 kbps
OHHTTPStubsDownloadSpeedWifi = -1500 = 1500 KB/s = 12000 kbps
Example:
return [[OHHTTPStubsResponse responseWithData:nil statusCode:400 headers:nil]
responseTime:OHHTTPStubsDownloadSpeed3G];- You can call
stubRequestsPassingTest:withStubResponse:multiple times. It will just add the stubs in an internal list of stubs.
This may be useful to install different stubs in various places in your code, or to separate different stubbing conditions more easily. See the OHHTTPStubsDemo project for a typical example.
When a network request is performed by the system, the stubs are tested in the reverse order that they have been added, the last added stub having priority over the first added ones.
The first stub that returns YES for the first parameter of stubRequestsPassingTest:withStubResponse: is then used to reply to the request.
- You can remove any given stub with the
removeStub:method. This method takes as a parameter theid<OHHTTPStubsDescriptor>object returned bystubRequestsPassingTest:withStubResponse:(Note: this returned object is already retained byOHHTTPStubswhile the stub is installed, so you should keep it in a__weakvariable so it is properly released from memory once removed). - You can remove the latest added stub with the
removeLastStubmethod. - You can also remove all stubs at once with the
removeAllStubsmethod.
This last one is useful when using OHHTTPStubs in your Unit Tests, to remove all installed stubs at the end of each of your test case to avoid stubs installed in one test case to be still installed for the next test case.
- (void)tearDown
{
[OHHTTPStubs removeAllStubs];
[super tearDown];
}You can add a name of your choice to your stubs. The only purpose of this is to easily identify your stubs for debugging, like when displaying them in the console.
id<OHHTTPStubsDescriptor> stub = [OHHTTPStubs stubRequestsPassingTest:... withStubResponse:...];
stub.name = @"Stub for text files";You can even imagine applying the .name = ... affectation directly (if you don't need to use the returned id<OHHTTPStubsDescriptor> otherwise), for a more concise syntax:
[OHHTTPStubs stubRequestsPassingTest:^BOOL(NSURLRequest *request) {
...
} withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) {
...
}].name = @"Stub for text files";You can then list all the installed stubs using [OHHTTPStubs allStubs], which returns an array of id<OHHTTPStubsDescriptor> objects so you can display their name on the console. This is useful to check that you didn't forget to remove some previous stubs that are still installed for example.
You can also setup a block that gets executed each time a request has been stubbed, using onStubActivation: method. This is typically useful to log the stub being used for each request:
[OHHTTPStubs onStubActivation:^(NSURLRequest *request, id<OHHTTPStubsDescriptor> stub) {
NSLog(@"%@ stubbed by %@", request.URL, stub.name);
}];