为 Moya 请求编写单元测试

问题描述 投票:0回答:3

我想开始为我所有的 Moya 请求编写测试用例。如何测试从 Swift 生成的简单 Moya

.get
请求?

testing moya
3个回答
8
投票

这就是我使用 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
本身,您可以查看 Moya 团队 是如何做到的。 由于存根会立即返回,因此不需要期望或类似的东西(这就是 Moya 团队测试的方式
.sampleData
)。

希望这有帮助!


0
投票

MOYA 为这种情况提供了很多便利。 您可以像这样简单地初始化您的存储库/网络请求(假设您有足够的使用 MOYA 的知识)

    init(testMode: Bool = false) {
    if testMode { 
      // If we want to mock API response with immediate response
        provider = MoyaProvider<Endpoint>(stubClosure: MoyaProvider<Endpoint>.immediatelyStub(_:))
    } else if delayedTestAPIMode { 
      // If we want to mock API response with some delay
        provider = MoyaProvider<Endpoint>(stubClosure: MoyaProvider<Endpoint>.delayedStub(3))
    } else { 
      // Actual response from server
        provider = MoyaProvider<Endpoint>(plugins: []) // Provide plugins if you have any
    }
}

然后在 Moya 的 TargetType 协议实现中返回您可能拥有的相应 API 的示例响应

var sampleData: Data {
    switch self {
    case .anyAPI:
        return sampleResponseEscapedJSON.utf8Encoded
    default:
     // Default response for every API
        return "{\"response_code\": 200, \"response_message\": \"Successfull\"}".utf8Encoded
    }
}

已使用的扩展

    private extension String {
    var utf8Encoded: Data { Data(self.utf8) }
}

-1
投票

您可以使用 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 完成处理程序。或其他任何东西。

© www.soinside.com 2019 - 2024. All rights reserved.