Testing
Moya has been created with testing at its heart. In this document, you will find all the customization points that will allow you to tailor your testing.
sampleData
When creating your TargetType
you are required to provide sampleData
for your targets. All you need to do there is to provide Data
that represents a sample response from every particular target. This can be used later for tests or just for providing offline support while developing.
For example:
public var sampleData: Data {
switch self {
case .userRepositories(let name):
return "[{\"name\": \"Repo Name\"}]".data(using: String.Encoding.utf8)!
}
}
stubClosure
The stubClosure
property of a MoyaProvider
is responsible for configuring whether a provider returns an actual or a stubbed response. This configuration is made in this closure by mapping a TargetType
to a case of the StubBehavior
enum:
.never
to not stub responses..immediate
to stub responses immediately..delayed(seconds: TimeInterval)
to stub responses after a given delay (to simulate the delays the real network calls may have).
For your convenience, MoyaProvider
defines the .immediatelyStub
and .delayedStub(:)
closures that you can set while initializing your provider to always stub responses immediately or with a given delay. For example, in the following provider all your requests are going to receive immediate responses with your sampleData
.
let stubbingProvider = MoyaProvider<GitHub>(stubClosure: MoyaProvider.immediatelyStub)
Before you continue, it is worth mentioning that all the stubbed responses will be delivered with an HTTP status 200
by default.
sampleResponseClosure
With the previous sampleData
and stubClosure
, we could only specify the data returned when stubbing. But you have more options.
Moya offers you the opportunity to configure an endpointClosure
on your provider. In this closure, your Target
needs to be mapped to an Endpoint
. Endpoint
is a semi-internal data structure used by Moya to reason about the request. And in this Endpoint
is where you are going to be able to specify more details for your testing. More concretely, on its sampleResponseClosure
.
As we discussed above, the default stubbing behavior is to respond to requests with your sample data with a 200
HTTP status code. This is because the default endpointClosure
defines its sampleResponseClosure
as follows:
{ .networkResponse(200, target.sampleData) }
If you need to setup your own sampleResponseClosure
, your implementation should return a case of the EndpointSampleResponse
enum:
- A
.networkResponse(Int, Data)
whereInt
is a status code andData
is the returned data. Useful to customize either response codes or data to your own specification. - A
.response(HTTPURLResponse, Data)
whereHTTPURLResponse
is the response andData
is the returned data. Useful to fully stub your responses. - A
.networkError(NSError)
whereNSError
is the error that occurred when sending the request or retrieving a response. Useful to test for any network errors: Timeouts, reachability issues, etc.
For example, the following code creates a provider to stub with immediate 401
responses:
let customEndpointClosure = { (target: APIService) -> Endpoint in
return Endpoint(url: URL(target: target).absoluteString,
sampleResponseClosure: { .networkResponse(401 , /* data relevant to the auth error */) },
method: target.method,
task: target.task,
httpHeaderFields: target.headers)
}
let stubbingProvider = MoyaProvider<GitHub>(endpointClosure: customEndpointClosure, stubClosure: MoyaProvider.immediatelyStub)