Unit Testing HTTP traffic in Alamofire app

前端 未结 4 959
闹比i
闹比i 2020-12-12 20:57

I\'m struggling a bit to figure out how to best test an app that uses Alamofire to help sync with server data.

I want to be able to test my code that uses Alamofire

4条回答
  •  甜味超标
    2020-12-12 21:35

    Waiting for an answer by @mattt I post an example of my code.

    Let's say that we have a Client class that is responsible for calling a simple web service. This class implements a function called userSignIn that performs a sign in using the WS.

    This is the code for the userSignIn function:

    func userSignIn(
            #email:String,
            password:String,
            completionHandler: (Bool, String?, NSError?) -> Void
            )-> Void
            {
    
                var parameters:[String:AnyObject] = [
                    "email":email,
                    "password":password,
                ]
    
    
                Alamofire.request(.POST, Client.urlPath, parameters: parameters, encoding: ParameterEncoding.JSON).responseJSON {
                    (request, response, JSON, responseError) -> Void in
    
                    // Setup callback params
    
                    // HERE WE INJECT THE "FAKE" DATA--------
                    var operationComplete = false
                    var accessToken:String?
                    var error:NSError?
                    // --------------------------------------
    
                    if let statusCode = response?.statusCode {
    
                        // Check for errors and build response data
                        (operationComplete, accessToken, error) = self.checkSignInResponse(statusCode, JSON: JSON)
                    }
    
                    // Call the completion handler
                    completionHandler(operationComplete, accessToken, error)
                }
        }
    

    The aim of the function is to get a token from the web service if the information passed by the user are correct.

    The function checkSignInResponse (I don't report its code since it's not useful for the answer) has the role to valorise the 3 variables operationComplete, accessToken and error depending on the JSON response received.

    Now that the 3 variables have a value we call the completionHandler using them.

    How to mock this function?!

    To mock the response I override the userSignIn function directly into the test function (as explained by the NSHipster article).

    func testUserSignIn_whenParamsAreInvalid(){
    
        class MockClient:Client {
    
            override func userSignIn(#email: String, password: String, completionHandler:
                (Bool, String?, NSError?) -> Void) {
    
                // Set callback params
                var operationComplete = false
                var accessToken:String? = nil
                var error:NSError? = NSError(domain: "Testing", code: 99, userInfo: nil)
    
                completionHandler(operationComplete, accessToken, error)
            }
        }
    
        signInViewController!.client = MockClient()
        signInViewController!.loadView()
    
        fillRegisterFieldsWithDataAndSubmit(femail(), password: fpassword())
    
        XCTAssertNotNil(signInViewController!.error, "Expect error to be not nil")
    
    }
    

    then I substitute the client inside the view controller that I'm testing using my "mocked" client. In this case I'm testing that the controller passes to the function information that are not valid so I check that the error property of the controller is not nil. To force this data I simply set operationComplete to false and I manual generate an NSError.

    Does it make any sense to you? I'm not sure that this test is a good test... but at least I can verify the data flow.

提交回复
热议问题