I want to start writing test cases for all my Moya requests. How can I test a simple Moya .get
request generated from Swift?

- 239,200
- 50
- 490
- 574

- 472
- 5
- 16
2 Answers
This is how I am doing my unit tests with Moya. I have my NetworkManager which makes all the requests and the init
with a default parameter (to use it on production code) so we can specify a different provider when testing.
class NetworkManager {
private let provider: MoyaProvider<MultiTarget>
init(provider: MoyaProvider<MultiTarget> = MoyaProvider<MultiTarget>()) {
self.provider = provider
}
func createUser(_ user: User, completion: @escaping (Result<User>) -> Void) {
provider.request(MultiTarget(UserApi.createUser(user: user))) { (result) in
switch result {
case .success(let response):
do {
let user = try response.map(User.self)
completion(.success(user))
} catch let error {
completion(.error(error))
}
case .failure(let error):
completion(.error(error))
}
}
}
// other requests...
}
So on production code you can have something like this:
let manager = NetworkManager()
let viewController = ViewController(networkManager: manager)
And on testing something like:
class TestMoyaTests: XCTestCase {
var networkManager: NetworkManager!
override func setUp() {
super.setUp()
networkManager = NetworkManager(provider: MoyaProvider<MultiTarget>(stubClosure: MoyaProvider.immediatelyStub))
}
func testGetUser() {
let expected = User(id: "1", name: "John")
var response: User?
networkManager.getUser(id: "1") { (result) in
if case let .success(user) = result {
response = user
}
}
XCTAssert(response == expected)
}
// other tests...
}
Or if what you are looking is to test the MoyaProvider
itself, you can check how Moya's team doing it.
Since the stubs are returned immediately, there is no need of expections or something like that (that is how Moya's team test .sampleData
).
Hope this helps!

- 2,551
- 19
- 25
-
What does the getUser() function did in your NetworkManager? – Raymond Liao Jan 29 '19 at 01:01
-
It will make an API call to fetch a user based on the id sent. In this case it should return a John user with id 1. – rgkobashi Jan 29 '19 at 06:37
-
same as the main app target: `import Moya` – rgkobashi Mar 25 '20 at 15:00
-
Couple of thoughts. 1. using a struct for a network manager is probably not a great idea. You really only ever want 1 so you will want to share it. 2. you're missing the fact that Moya wants you to return stubbed data from the sampleData method. Adding this to you answer would improve its usefulness. – SmileBot Jun 26 '21 at 21:32
-
@smileBot right, I have updated my reply, your point no.2 didnt get it though – rgkobashi Jun 28 '21 at 04:32
You can use OCMock to stub the completion handler and return your own completions handlers. Example -
__block UIView *mockViewAnimation;
__block void(^animationsBlock)(void);
__block void(^completionBlock)(BOOL);
beforeEach(^{
void (^viewAnimation)(NSInvocation *) = ^(NSInvocation *invocation) {
[invocation retainArguments];
[invocation getArgument:&animationsBlock atIndex:5];
[invocation getArgument:&completionBlock atIndex:6];
};
mockViewAnimation = OCMClassMock([UIView class]);
// This stub tests the animation with duration, delay, and options
// Animation and Completion aren't tested here because they'll have their own tests.
OCMStub([mockViewAnimation animateWithDuration:1
delay:0
options:UIViewAnimationOptionCurveEaseIn
animations:[OCMArg any]
completion:[OCMArg any]]).andDo(viewAnimation);
[sut viewDidLoad];
});
and then you can call animationsBlock(); or completionBlock(YES);
This is an example to mock the completion handlers, you can use same logic to mock Mayo completion handlers. or anything else.

- 354
- 3
- 10