2012-08-23 9 views
19

que tienen una función en mi servicio que se ve como algo esto:

addStatement: function(user, action, object) { 
      var statement = { 
        user: user, 
        action: action, 
        object: object 
      }; 
      $http({ 
       method: 'POST', 
       url: '/foo/bar', 
       data: statement, 
       headers: {Authorization: 'Basic YWxhZGRpbjpvcGVuIHNlc2FtZQ=='} 
      }).success(function(data) { 
       alert("success: " + data); 
      }); 
     } 

Quiero escribir una prueba unitaria para este método, pero no estoy seguro Cómo hacer que funcione. Básicamente, quiero probar que los datos enviados se construyeron correctamente a partir de los parámetros de la función y que se envió el encabezado de Autorización correcto.

He estado leyendo sobre cómo usar $httpBackend, pero el ejemplo está probando un controlador, y solo cosas que cambian en el $ scope cuando las solicitudes son hechas y devueltas. ¿Hay alguna manera de lograr las pruebas que quiero? ¿O estoy haciendo algo mal?

Respuesta

37

Los servicios de prueba no difieren mucho de los controladores de prueba, por lo que los principios son los mismos. Básicamente lo que necesita:

  • Inyectar objetos bajo prueba
  • se burla de configuración (si lo hay) - aquí usted estaba en el camino correcto uso de $ httpBackend simulacros
  • métodos se ejecutan en el objeto a prueba y verificar los resultados

Si después de probar que un métodos de servicio resultados en post http $ llaman podría escribir su prueba como esta (partes no esenciales omitidos):

beforeEach(module('MyApp')); 
beforeEach(inject(function(MyService, _$httpBackend_) { 
    service = MyService; 
    $httpBackend = _$httpBackend_; // angular strips the underscores so 
            // we don't need to use unique names 
    // https://docs.angularjs.org/api/ngMock/function/angular.mock.inject 
})); 

it('should invoke service with right paramaeters', function() { 
    $httpBackend.expectPOST('/foo/bar', { 
     "user": "testUser", 
     "action": "testAction", 
     "object": {} 
    }, function(headers){ 
     return headers.Authorization === 'Basic YWxhZGRpbjpvcGVuIHNlc2FtZQ=='; 
    }).respond({}); 
    service.addStatement('testUser', 'testAction', {}); 
    $httpBackend.flush(); 
}); 

Aquí es el jsFiddle de trabajo que ilustra esta prueba en acción: http://jsfiddle.net/pkozlowski_opensource/MkrjZ/2/

Una última observación: es mejor no utilizar .alert() en las pruebas de unidad ya que esas alertas hará una pausa ejecución de las pruebas.

+0

+1 para evitar 'alert's. Otra posibilidad es que quieras inyectar '$ window' y usar' $ window.alert' para que puedas simular eso para tus pruebas. – btford

+0

Momento de aprendizaje: si saca '$ httpBackend.flush();' su prueba no será la esperada. –

2

escribí un post sobre ese mismo tema mostrando un poco sobre el uso de angulares burla incorporados y escribir sus propios burla, tal vez le ayuda a obtener una comprensión más profunda:

How to mock AngularJS modules and inject them in your testacular tests?

En corto que define un segundo módulo para las pruebas que pueden burlarse del comportamiento deseado:

var apptastic  = angular.module('apptastic', []), 
    apptasticMock = angular.module('apptasticMock', []); 

y sobrescribe el comportamiento original, por ejemplo, de esta manera:

apptasticMock.service("socket", function($rootScope){ 
... // overwrite 
}); 

Entonces tiene que ser cargada en las pruebas - Esto funciona porque sobrescribe angulares ya definidos servicios en el orden en que se cargan:

describe("Socket Service", function(){ 
    var socket; 

    beforeEach(function(){ 
    module('apptastic'); 
    module('apptasticMock'); 

    inject(function($injector) { 
     socket = $injector.get('socket'); 
    }); 
    }); 

    it("tests something", function(){ 
    ... // test 
    }); 

}); 

con una bonita estructura del código, incluso la herencia no es realmente un problema mientras se puede tener un control detallado sobre qué se debe burlar y qué se debe usar del código original.

Cuestiones relacionadas