2016-01-12 110 views
9

Ho sviluppato un'applicazione Web utilizzando Angular JS. Ricevo pochi CR aggiuntivi che devono essere implementati nell'uso dell'approccio TTD. Abbiamo casi di test unitari di ritorno con Jasmine e Karma. La sfida che stiamo affrontando è quando proviamo a scrivere un caso di test unitario per più controller. Ho un ritorno pagina principale su Home Controller & ha un evento di trasmissione in un altro controller. Quando scrivo un caso di test unitario, l'oggetto per il controller che ha questo evento di trasmissione non è inizializzato.Angular JS Test driven Sviluppo con più controller

C'è un modo per iniettare il secondo controller come oggetto dipendente. Le risposte con link di esempio Reference o codice dimostrativo sono molto apprezzate.

+0

Penso che il thread del metodo di test stia emettendo come thread univoco perché cross library non può avere thread multipli. Si può provare a scrivere un factory di inizializzazione degli eventi sul controller principale per casi di test speciali. Non ho avuto questo solo penso – dewelloper

risposta

9

Si dichiara che si sta utilizzando Jasmine e Karma, quindi presumo che si stia eseguendo un test unitario. Se si esegue un test "unitario", è necessario testare singolarmente ciascun controller mentre si fa il tifo, la spia e tutti i servizi iniettati.

beforeEach(inject(function ($rootScope, $controller) { 
     rootScope = $rootScope; 
     scope = $rootScope.$new(); 
     controller = $controller('MyCtrl as ctrl', { 
      '$scope': scope 
     });    
    })); 

    it('', function(){ 

    //Arrange 
    controller.counter = 0; // Your controller is listening on scope.$on to update this counter. 

    //Act 
    rootScope.$broadcast('xyz', {}); 

    //Assert 
    expect(controller.counter == 1).toBe(true); 
    rootScope.$broadcast('xyz', {}); 
    expect(controller.counter == 2).toBe(true); 
    rootScope.$broadcast('xyz', {}); 
    expect(controller.counter == 3).toBe(true); 
    }); 

Basta fare attenzione con la trasmissione. Solo gli eventi di un dominio (modello aggiornato/cancellato/creato), o qualcosa di globale (signin, signout) dovrebbero viaggiare su $ broadcast. Altrimenti, dovrebbe essere sostituito con un servizio + direttiva. Un esempio è il materiale angolare https://material.angularjs.org/latest/api/service/ $ mdDialog che è 1 direttiva con un servizio di supporto che può essere aperto/chiuso da qualsiasi posizione.

2

È possibile iniettare qualsiasi controller con il servizio $ controller, ad es.

beforeEach(inject(function ($rootScope, $controller) { 
      scope = $rootScope.$new(); 
      controller = $controller('MyCtrl', { 
       '$scope': scope 
      }); 
     })); 

vedi Documentazione qui: https://docs.angularjs.org/api/ngMock/service/ $ regolatore

così quello che devi fare è iniettare tale controller prima, allora il vostro altro controller. allora il primo controller sarà istanziato nel momento in cui il secondo viene istanziato.

1

Sono nuovo di angolare, sembra essere possibile iniettare più controller contemporaneamente. Tuttavia, la best practice consiste nel generare un controller mock che si comporta come ci si aspetta che si comporti il ​​secondo controller. Questo riduce il numero di cose che stai testando in una volta. Il seguente link può essere utile per creare un controller fittizio, http://www.powdertothepeople.tv/2014/08/28/Mocking-Controller-Instantiation-In-AngularJS-Unit-Test/.