¿Cómo hago la prueba unitaria $ scope.broadcast, $ scope. $ Sobre el uso de Jasmine

Soy un novato en el mundo de AngularJs / NodeJs, así que perdona si esta es una pregunta básica para algunos.

Así que en pocas palabras tengo dos controladores, el primer controlador $broadcast una ‘Id’ y el segundo controlador recupera esa Id con $on y luego pasa esa Id a un service intermedio, lo que hace una llamada $http ajax y devuelve una sola Objeto Book .

¿Cómo hago la prueba unitaria $ scope.broadcast, $ scope. $ Sobre el uso de Jasmine

FirstCtrl

 .controller('firstCtrl', function($scope, ...){ $scope.selectGridRow = function() { if($scope.selectedRows[0].total !=0) $scope.$broadcast('id', $scope.selectedRows[0].id);//Just single plain ID }; }); 

secondCtrl

 .controller('secondCtrl', function($scope, bookService) { $scope.$on('id', function(event, id) { bookService.getBookDetail(id).then(function(d) { $scope.book = d.book; }); }); }); 

esperado Json obj

 var arr = "book" : [ { "id" : "1", "name" : "Tomcat", "edition" : "9.1" } ] 

Avíseme si alguien quiere que publique el servicio $http que usa el segundo controlador.

comportamiento esperado

Así que desde lo más alto de mi cabeza, idealmente, me gustaría probar todos los escenarios posibles, pero algo como lo siguiente, que luego puedo gastar:

 expect(scope.book).toEqual(arr); expect(scope.book).not.toEqual(undefined); 

¡Gracias a todos!

Primero debe hacer la transmisión en $rootScope luego puede recibir en $scope . Ahora a la prueba. Supongo que desea incluir una solicitud real a su API a través de bookService y $http . Esto puede ser burlado, pero me centraré en la llamada real. Déjame saber si necesitas el burlado.

Antes de la prueba real, deberá realizar algunas inyecciones / instancias:

  • Inicializa tu aplicación
  • Inyectar $controller , $rootScope , $httpBackend y bookService
  • Cree ámbitos para firstController y SecondController y almacénelos en una variable
  • Almacenar bookService y $httpBackend en variables
  • Instalar los controladores y almacenarlos.

Luego, en la prueba real, debe indicar a $httpBackend qué hacer cuando almacena en caché la solicitud de los libros (o libros). Construya $httpBackend.whenGET("/api/books/1").passThrough(); pasará la solicitud con url "/api/books/1" al servidor. A continuación, debe configurar la propiedad selectedRows en firstScope para que cumpla la condición en la función selectGridRow en su firstCtrl .

Ahora puede llamar a la función selectGridRow para activar la difusión y la llamada a la API. Pero debes envolverlo en la función de ejecución para que Jasmine reconozca esto como una llamada asíncrona y esperará a que termine. La ‘espera’ se define en la llamada waitsFor . Esperará hasta que reciba un libro y espere un máximo de 5000 ms, luego la prueba se marcará como fallida.

El último paso es verificar el resultado esperado. Ya no tenemos que verificar si undefined ya que la prueba no llegaría aquí de todos modos. La comprobación debe volver a ajustarse, se runs llamada para que se ejecute después de ‘waitsFor’ exitoso.

Aquí está el código completo:

 describe("Broadcast between controllers", function () { beforeEach(module('app')); //app initialization var firstScope; var secondScope; var bookService; var $httpBackend; var firstController; var secondController; beforeEach(inject(function ($controller, $rootScope, _bookService_, _$httpBackend_) { firstScope = $rootScope.$new(); secondScope = $rootScope.$new(); bookService = _bookService_; $httpBackend = _$httpBackend_; firstController = $controller('firstCtrl', { $scope: firstScope }); secondController = $controller('secondCtrl', { $scope: firstScope, bookService: bookService }); })); it("should work", function () { $httpBackend.whenGET("/api/books/1").passThrough(); firstScope.selectedRows = [{ id: 1, total: 1000 }]; secondScope.book = null; runs(function () { firstScope.selectGridRow(); }); waitsFor(function () { return secondScope.book != null; }, "Data not received in expected time", 5000); runs(function () { expect(secondScope.book[0].id).toEqual(1); }); }); });