2013-08-11 10 views
8

Sto cercando di capire come testare il mio codice con jasmine e angularJS. Ho scritto un progetto di test con un controller e un servizio di iniezione. Ora voglio testare il controller e ho provato a prendere in giro il servizio iniettato. Ma non ho trovato un modo per testare la funzione "Arrivata" dal mio controller. Ecco il mio jsfiddle: http://jsfiddle.net/2fwxS/Test del controller con servizio di iniezione all'interno di angularJS con gelsomino

controller.js:

angular.module('myApp.controllers', []) 
    .controller('MyCtrl', ['$scope', 'MyService', function ($scope, MyService) { 
    $scope.User = {}; 
    $scope.HasUserArrived = false; 
    $scope.Arrived = function(firstname, lastname) { 
    $scope.HasUserArrived = MyService.Arrive(firstname, lastname); 
    return $scope.HasUserArrived; 
    } 
}]); 

services.js:

var myApp = angular.module('myApp.services', []). 
    value('version', '0.1'); 

myApp.factory('MyService', [function() { 
    return { 
     HasArrived: false, 
     Arrive: function (firstname, lastname) { 
      this.HasArrived = false; 

      if (firstname && lastname) { 
       this.HasArrived = true; 
      } 

      console.log("User has arrived: " + this.HasArrived); 
      return this.HasArrived; 
     } 
    } 
}]); 

ho trovato alcune spiegazioni simili dove $ forniscono potrebbe essere il soluzione corretta (How can I write jasmine test for angular controller and service like this?) o createSpy (How do you mock Angular service that is a function?) ma non ero in grado di capire quando ho bisogno di $ provider.factory o $ provider.value o quando dovrei usare createSpy?

Gradirei se qualcuno potesse aiutarmi a capire le differenze e ottiene il codice disattivato nel mio jsFiddle (http://jsfiddle.net/2fwxS/) esempio installato e funzionante ...

risposta

10

Si dovrebbe usare $provide.value al fine di sostituire l'istanza del servizio originale con un deriso uno:

beforeEach(module(function($provide) { 
    var service = { 
     Arrive: function (firstname, lastname) { 
      if (firstname && lastname) { 
       return true; 
      } 
     } 
    }; 
    $provide.value('MyService', service); 
})); 

io davvero non so perché $provide.value opere ma $provide.factory non lo fa. Cercherò di dare un'occhiata al codice angolare in seguito, così posso capirlo. Aggiornerò questa risposta se scoprirò qualcosa.

Per quanto riguarda le spie, dovresti usarle se vuoi verificare che le tue finte siano utilizzate nel modo in cui dovrebbero. Ciò include il controllo di parametri e invocazioni. Ecco il codice modificato per usare una spia:

it('checks that Arrived is correctly used', function() { 
    // Arrange 
    spyOn(service, 'Arrive'); 

    // Act 
    scope.Arrived('Franz', 'Kafka'); 

    // Assert 
    expect(service.Arrive).toHaveBeenCalledWith('Franz', 'Kafka'); 
}); 

Ecco la tua fissa jsFiddle.

+0

Siamo spiacenti per la mia risposta in ritardo! @ Michael Grazie per la risposta e il corretto jsFiddle. Con quei piccoli cambiamenti sono riuscito a eseguire i miei test con successo! In effetti sarebbe bello sapere perché la fabbrica non funziona. – burgerS

+0

E il mio collega e io siamo interessati se c'è anche un modo per testare il servizio all'interno di questo esempio invece di prendere in giro il servizio. Sappiamo che dovremmo testare il servizio separatamente, ma ci chiedevamo se fosse possibile testare il servizio all'interno di questo esempio ... – burgerS

+1

Puoi cavartela con il servizio di derisione per testare il controller se il servizio è molto semplice e puoi prevedere in modo sicuro il suo comportamento, riducendo così al minimo le probabilità di rompere i test del controller a causa di un errore nell'implementazione del servizio. Ma, se lo fai, testerai il controller, non il servizio. Dovresti comunque testare il servizio separatamente così puoi assicurarti che funzioni come dovrebbe. –

Problemi correlati