unitarias unitaria una software que pruebas prueba para metodologia interfaz informe ejemplo diseñar unit-testing alamofire

unit testing - unitaria - Unidad de pruebas de tráfico HTTP en la aplicación Alamofire



pruebas unitarias php (3)

Esperando una respuesta de @mattt publico un ejemplo de mi código.

Digamos que tenemos una clase de Client que es responsable de llamar a un servicio web simple. Esta clase implementa una función llamada userSignIn que realiza un inicio de sesión utilizando el WS.

Este es el código para la función userSignIn :

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

El objetivo de la función es obtener un token del servicio web si la información transmitida por el usuario es correcta.

La función checkSignInResponse (no checkSignInResponse su código, ya que no es útil para la respuesta) tiene la función de valorizar las 3 variables operationComplete , accessToken y error según la respuesta JSON recibida.

Ahora que las 3 variables tienen un valor, llamamos a completionHandler usándolas.

¿Cómo burlarse de esta función?

Para simular la respuesta, userSignIn función userSignIn directamente en la función de prueba (como se explica en el artículo de NSHipster).

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") }

Luego sustituyo al client dentro del controlador de vista que estoy probando usando mi cliente "simulado". En este caso, estoy probando que el controlador pasa a la información de la función que no es válida, así que verifico que la propiedad de error del controlador no sea nula. Para forzar estos datos simplemente establezco operationComplete en falso y genero manualmente un NSError .

¿Tiene algún sentido para ti? No estoy seguro de que esta prueba sea una buena prueba ... pero al menos puedo verificar el flujo de datos.

Estoy luchando un poco para encontrar la mejor manera de probar una aplicación que utiliza Alamofire para ayudar a sincronizar con los datos del servidor.

Quiero poder probar mi código que utiliza Alamofire y procesa las respuestas JSON de un servidor. Me gustaría burlarme de esas pruebas para poder enviar los datos de respuesta esperados a esas pruebas sin incurrir en tráfico de red real.

Esta publicación del blog ( http://nshipster.com/xctestcase/ ) describe lo fácil que es simular un objeto en Swift, pero no estoy seguro de cómo hacerlo con Alamofire y sus respuestas encadenadas.

¿Me burlaría del gerente? ¿la solicitud? ¿Respuesta? ¡Cualquier ayuda sería apreciada!


Esta pregunta se está haciendo vieja, pero acabo de encontrar el mismo problema y la solución es muy sencilla cuando se usan OHHTTPStubs.

OHHTTPStubs simplemente se burla de las respuestas que recibe de NSURLSession, por lo que funciona bien con Alamofire, y obtiene una muy buena cobertura de la ruta de su código.

Por ejemplo, en su caso de prueba, simplemente se burla de la respuesta usando:

OHHTTPStubs.stubRequestsPassingTest({ (request: NSURLRequest) -> Bool in return request.URL!.host == "myhost.com" }, withStubResponse: { (request: NSURLRequest) -> OHHTTPStubsResponse in let obj = ["status": "ok", "data": "something"] return OHHTTPStubsResponse(JSONObject: obj, statusCode:200, headers:nil) })


Estoy agregando otra respuesta ya que acabo de encontrar este enfoque que, en mi opinión, es más fácil y realmente fácil de leer y usar.

He creado una clase ficticia de Alamofire que contiene solo las funciones y los tipos necesarios para las pruebas. Ahora incluyo este archivo en el objetivo de prueba en lugar del Alamofire real.

Por ejemplo, he creado mi versión de la clase de Request donde defino un par de variables estáticas que valorizo ​​según la prueba, y para esta clase implementé solo la función init y responseJSON .

public class Request { var request:String? struct response{ static var data:NSHTTPURLResponse? static var json:AnyObject? static var error:NSError? } init (request:String){ self.request = request } public func responseJSON(options: NSJSONReadingOptions = .AllowFragments, completionHandler: (NSURLRequest, NSHTTPURLResponse?, AnyObject?, NSError?) -> Void) -> Self { completionHandler(NSURLRequest(URL: NSURL(string:self.request!)!), Request.response.data, Request.response.json, Request.response.error) return self } }

Ahora puedo burlar una respuesta en una prueba:

func testMytestFunction(){ var HTMLResponse = NSHTTPURLResponse(URL: NSURL(string: "myurl")!, statusCode: 200, HTTPVersion: "HTTP/1.1", headerFields: nil) Request.response.data = HTMLResponse Request.response.json = LoadDataFromJSONFile("MyJsonFile") request(.POST, "myurl", parameters: nil, encoding: ParameterEncoding.JSON).responseJSON { (request, response, JSON, error) -> Void in // the JSON and response variable now contains exactly the data that you have passed to Request.response.data and Request.response.json } }

La función de solicitud se define aquí:

public func request(method: Method, URLString: URLStringConvertible, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL) -> Request { return Request(request: URLString.URLString) } public func request(URLRequest: URLRequestConvertible) -> Request { return Request(request: "fakecall") }