来自enum的Swift 3 Access字典(json)值

时间:2017-06-16 15:53:09

标签: swift enums

我试图使用这篇文章https://8thlight.com/blog/mike-knepper/2017/01/30/keeping-third-party-swift-dependencies-testable.html中描述的枚举,并且在理解如何使用枚举返回作为我的回复时遇到一些麻烦。我已经为成功的测试设置了我的代码(暂时删除了失败和错误的情况):

枚举响应返回定义:

public struct Constants {
    public typealias jsonData = [String: Any]
    public typealias jsonErrors = [[String: Any]]
}
public enum ServiceResponse {
    case success(Constants.jsonData)
    case errors(Constants.jsonErrors)
    case failure(String)
}

我的模拟回复:

private let successData: Constants.jsonData = [
    "user_email": "tester@ci.com",
    "user_display_name": "tester smith",
    "user_avatar_url": "",
    "user_id": 1
]

private let successfulResponse = ServiceResponse.success(successData)

模拟适配器(用于我的测试)为:

class MockSuccessfulNetworkAdapter: NetworkAdapter {
    func post(destination: String, payload: [String: Any], responseHandler: @escaping (ServiceResponse) -> ()) {
        responseHandler(successfulResponse)
    }
}

我正在测试的服务是:

    public func validateUser(_ userData: [String: Any]?, completed: ((_ response: ServiceResponse) -> ())? ) {

        let loginEndpoint = "\(Constants.BASE_ENDPOINT)\(Constants.LOGIN_ENDPOINT)"
        if let userPayload = userData {

            networkAdapter.post(destination: loginEndpoint, payload: userPayload, responseHandler: { (response) -> Void in
                print("User validate call response was \(response)")               
                completed?(response)
            })
        }
        else {
            print( "Invalid User attempt to write JSON")
            return
        }
    }

测试(我尝试过的一些途径):

func testValidateAValidUser() {
    let networkAdapter = MockSuccessfulNetworkAdapter()

    if  let loginService = LoginService(Constants.BASE_ENDPOINT, networkAdapter) {
        let userData = [
            "email": "tester@a.com",
            "password": "password"
        ]

        loginService.validateUser(userData, completed: { (response: ServiceResponse?) -> Void in
            print(response)

                // case ServiceResponse.success (let data) {

                    print("Response for validate user -> \(response!)")
//                    var data = response? as! Constants.jsonData
//                    if (response == ServiceResponse.success(data)) {
//                        // let em = response ["email"]
//                    }
                // XCTAssertTrue(response == ServiceResponse.success)
                // if let em = response ["email"] {
                    print("OK!!")
                // }
                // XCTAssertTrue( , "tester@ci.com")
            // }
            })
        }
    }    

我喜欢在我的测试中使用枚举和依赖注入的想法,但似乎无法获得实际值(当我移动到alamofire或者解码实际的东西时我将不得不这样做)价值观。非常感谢任何帮助!

编辑:添加回复

我在运行测试时看到的答案是正确的: enter image description here

1 个答案:

答案 0 :(得分:1)

所以你几乎就在那里,获取枚举大小写值的最简单方法就是使用switch语句,大小写所有情况(lol),并在参数中指定let常量。 testValidate函数中的validateUser方法如下所示:

loginService.validateUser(userData, completed: { (response: ServiceResponse?) -> Void in
        print(response)

        guard let resp = response else {
            return
        }

        switch resp {
        case .errors(let error) :
            print(error)
        case .failure(let failed) :
            print(failed)
        case .success(let json) :
            print(json)
            //execute your json..
        }
    })

我发现了一篇有趣的文章,涉及到这样一个用例: https://medium.com/@jbergen/you-ve-been-using-enums-in-swift-all-wrong-b8156df64087

此外,由于您遇到错误并且响应失败。我会删除可选的响应回复变量,您可以根据您的网络任务提供正确的ServiceResponse案例;因此不需要打开包装。值得深思!