Network Timeout
RLovelett opened this issue · 5 comments
Is there anyway to simulate a network timeout with Vinyl?
I've been playing around with this and I'm not sure that there is a way to simulate a network timeout or other types of network issues currently with Vinyl.
So I'm interested in feedback on adding a slight variation of the Vinyl fixture format. One that handles a good response and one that handles a bad response.
The format would largely be the same as before except that the "response"
JSON property could now have an "error"
property which would be mapped into an NSError
. This NSError
would then be provided during Vinyl playback.
[
{
"request": {
"url": "http://api.test.com"
},
"response": {
"error": {
"code": -1006,
"domain": "NSURLErrorDomain",
"userInfo": {
"NSErrorFailingURLKey": "http://api.test.com",
"NSErrorFailingURLStringKey": "http://api.test.com",
"NSLocalizedDescription": "A server with the specified hostname could not be found."
}
},
"url": "http://api.test.com"
}
}
]
Thoughts?
You can simulate a network timeout by creating a vinyl programmatically and provide the expected NSError
using this specific API.
For this kind of tests I think creating a vinyl programmatically is more appropriate since you can use constants instead of hard-coded strings that should map without guarantees to a NSError
.
That seems fair and I kind of like that too. Though it does feel disjointed that some of my test fixtures will be in files and some of my test fixtures will be inline. Cannot say it matters too much. Just thought I'd point that out.
Of course, the major problem is that it does not work properly, at least not yet.
func testNotMocked() {
let expectation = self.expectationWithDescription(#function)
defer { self.waitForExpectationsWithTimeout(50.0, handler: nil) }
let url = NSURL(string: "http://dfsdfhttpbin.org/hidden-basic-auth/:user/:passwd")!
let session = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
session.dataTaskWithURL(url) { (data, response, error) in
XCTAssertNil(data)
XCTAssertNil(response)
XCTAssertNotNil(error)
print(error)
expectation.fulfill()
}.resume()
}
func testMocked() {
let expectation = self.expectationWithDescription(#function)
defer { self.waitForExpectationsWithTimeout(50.0, handler: nil) }
let url = NSURL(string: "http://dfsdfhttpbin.org/hidden-basic-auth/:user/:passwd")!
let error = NSError(domain: NSURLErrorDomain, code: NSURLErrorDNSLookupFailed, userInfo: nil)
let track = [TrackFactory.createBadTrack(url, statusCode: 400, error: error)]
let vinyl = Vinyl(tracks: track)
let turntable = Turntable(vinyl: vinyl)
turntable.dataTaskWithURL(url) { (data, response, error) in
XCTAssertNil(data)
XCTAssertNil(response)
XCTAssertNotNil(error)
print(error)
expectation.fulfill()
}.resume()
}
The testNotMocked
one comes through without a problem. The testMocked
on the other-hand does not. The second one's response
is not nil
and fails the assertion.
It would seem to me that Response
needs to be refactored to have an NSHTTPURLResponse?
instead of NSHTTPURLResponse
. Agree?
Well spotted, yes it need to be optional since we may not have one, when there's an error. This can be confirmed in NSURLSession
's methods like this one.
I'm currently on vacation so I'm not able to work on this until the weekend but PRs are welcome ✨
@dmcrodrigues there is a pull for this at #62.