为 Moya 请求编写单元测试

Posted

技术标签:

【中文标题】为 Moya 请求编写单元测试【英文标题】:Writing unit tests for a Moya request 【发布时间】:2017-06-09 09:47:45 【问题描述】:

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

【问题讨论】:

【参考方案1】:

这就是我使用 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's team 是如何做到的。 由于存根会立即返回,因此不需要期望或类似的东西(Moya 的团队就是这样测试.sampleData)。

希望这会有所帮助!

【讨论】:

你的 NetworkManager 中的 getUser() 函数做了什么? 它将根据发送的 id 进行 API 调用以获取用户。在这种情况下,它应该返回一个 ID 为 1 的 John 用户。 与主应用目标相同:import Moya 几个想法。 1. 为网络管理器使用结构可能不是一个好主意。你真的只想要 1 所以你会想要分享它。 2.您错过了 Moya 希望您从 sampleData 方法返回存根数据的事实。将此添加到您的答案中将提高其实用性。 @smileBot 对,我已经更新了我的回复,但是你的第 2 点没明白【参考方案2】:

您可以使用 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();或完成块(YES);

这是一个模拟完成处理程序的示例,您可以使用相同的逻辑来模拟 Mayo 完成处理程序。或其他任何东西。

【讨论】:

以上是关于为 Moya 请求编写单元测试的主要内容,如果未能解决你的问题,请参考以下文章

如何为 Python socketserver 请求处理程序编写单元测试?

烧瓶单元测试:如何测试来自登录用户的请求

如何在 Django 单元测试中获取请求对象?

单元测试给出 NullPointerException

Android单元测试

如何为具有 Spring Security 配置的 Spring Boot API 编写单元测试