Написание модульных тестов для запроса Moya

Я хочу начать писать тестовые примеры для всех моих запросов Moya. Как я могу протестировать простой запрос Moya .get, сгенерированный Swift?


person dhamini poornachandra    schedule 09.06.2017    source источник


Ответы (2)


Вот как я выполняю свои модульные тесты с Moya. У меня есть NetworkManager, который выполняет все запросы, и init с параметром по умолчанию (чтобы использовать его в производственном коде), поэтому мы можем указать другого поставщика при тестировании.

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...
}

Итак, в производственном коде может быть что-то вроде этого:

let manager = NetworkManager()
let viewController = ViewController(networkManager: manager)

А по тестированию что-то вроде:

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...
}

Или, если вы хотите протестировать сам MoyaProvider, вы можете проверить, как Команда Мойи делает это. Так как заглушки возвращаются немедленно, не нужно никаких ожиданий или чего-то подобного (так команда Мойи тестирует .sampleData).

Надеюсь это поможет!

person rgkobashi    schedule 22.02.2018
comment
Что делает функция getUser () в вашем NetworkManager? - person Raniys; 29.01.2019
comment
Он выполнит вызов API для выборки пользователя на основе отправленного идентификатора. В этом случае он должен вернуть пользователя John с идентификатором 1. - person rgkobashi; 29.01.2019
comment
то же, что и основная цель приложения: import Moya - person rgkobashi; 25.03.2020
comment
Пару мыслей. 1. Использование структуры для сетевого менеджера, вероятно, не лучшая идея. Вы действительно хотите только 1, поэтому вы захотите поделиться им. 2. вам не хватает того факта, что Мойя хочет, чтобы вы вернули данные-заглушки из метода sampleData. Добавление этого к вашему ответу повысит его полезность. - person smileBot; 27.06.2021
comment
@smileBot right, я обновил свой ответ, но ваш пункт № 2 не понял - person rgkobashi; 28.06.2021

Вы можете использовать OCMock, чтобы заглушить обработчик завершения и вернуть свои собственные обработчики завершения. Пример -

__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];
    });

а затем вы можете вызвать animationsBlock (); или ЗавершениеБлок (ДА);

Это пример имитации обработчиков завершения, вы можете использовать ту же логику для имитации обработчиков завершения Mayo. или что-нибудь еще.

person Jasveer Singh    schedule 09.06.2017