2016-01-12 6 views
9

Ich habe eine Webanwendung mit Angular JS entwickelt. Ich bekomme wenige zusätzliche CR, die in TTD-Ansatz implementiert werden muss. Wir haben Return Unit Test Cases mit Jasmine und Karma. Die Herausforderung, vor der wir derzeit stehen, ist, wenn wir versuchen, Unit-Test-Case für mehrere Controller zu schreiben. Ich habe eine Hauptseite Rückkehr zum Home Controller & es hat ein Broadcast-Ereignis in einem anderen Controller. Wenn ich ein Unit-Test-Case schreibe, wird das Object für den Controller, der dieses Broadcast-Ereignis hat, nicht initialisiert.Angular JS Testgetriebene Entwicklung mit mehreren Controllern

Gibt es eine Möglichkeit, den zweiten Controller als abhängiges Objekt zu injizieren. Antworten mit Referenzbeispiel Link oder Demo-Code wird sehr geschätzt.

+0

Ich denke, dass der Thread der Testmethode als Uniq-Thread aufgrund der Cross-Bibliothek ausgibt, könnte nicht Multy-Thread haben. Sie können versuchen, eine Ereignisinitialisierungsfactory auf Ihrem Hauptcontroller für spezielle Testfälle zu schreiben. Ich hatte das nicht nur, denke ich – dewelloper

Antwort

9

Sie sagen, Sie verwenden Jasmine und Karma, also nehme ich an, Sie sind Unit-Tests. Wenn Sie "Unit" testen, sollten Sie jeden Controller einzeln testen, während Sie alle injizierten Dienste verspotten, spionieren.

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

Seien Sie vorsichtig mit Broadcast. Nur Domain-Ereignisse (Modell aktualisiert/gelöscht/erstellt) oder etwas Globales (Sign-in, Sign-Out) sollten über $ Broadcast laufen. Andernfalls sollte es durch eine Service + Direktive ersetzt werden. Ein Beispiel ist das eckige Material https://material.angularjs.org/latest/api/service/ $ mdDialog, das eine Direktive mit einem Backing-Service ist, der von überall geöffnet/geschlossen werden kann.

2

Sie können einen beliebigen Controller mit dem $ controller-Dienst injizieren, z.

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

sehen hier docs: https://docs.angularjs.org/api/ngMock/service/ $ controller

so, was Sie tun injizieren, dass die Steuerung zuerst, dann die anderen Controller. Dann wird der erste Controller zum Zeitpunkt der Instanziierung des zweiten Controllers instanziiert.

1

Ich bin neu in eckig, es scheint möglich, mehrere Controller gleichzeitig zu injizieren. Die beste Vorgehensweise besteht jedoch darin, einen vorgetäuschten Controller zu generieren, der sich so verhält, wie Sie erwarten, dass sich der zweite Controller verhält. Dies reduziert die Anzahl der Dinge, die Sie gleichzeitig testen. Der folgende Link kann hilfreich sein, um einen Mock-Controller zu erstellen, http://www.powdertothepeople.tv/2014/08/28/Mocking-Controller-Instantiation-In-AngularJS-Unit-Test/.