2016-11-16 3 views
3

Hallo stackoverflow-Community.Testen einer Funktion in einer Komponente in einer Komponente, die die Methode zur übergeordneten Komponente aufruft

Ich arbeite an einem Angular-Projekt (1.5.6), verwende eine Komponentenstruktur und schreibe gerade einige Komponententests. Ich lerne immer noch viel über Komponententests - besonders in Bezug auf Angular - und hoffte, dass ich Sie um Hilfe für das folgende Problem bitten kann:

Ich versuche, eine Komponente zu testen, die eine Callback-Methode von der übergeordneten Komponente erhält . Ich versuche die Methode foo zu verspotten (siehe unten das Codebeispiel). Und leider ruft diese Methode den übergeordneten Controller.

Also wenn ich versuche es zu testen, klagt es, dass die Methode nicht definiert ist. Dann dachte ich, ich könnte es mit SpyOn spotten, aber dann bekomme ich den Fehler Error: <spyOn> : foobar() method does not exist

Also ich denke, ich bin nicht in der Lage, diese Methode zu verspotten.

Modul:

angular.module("myApp") 
.component("sample", { 
    "templateUrl": "components/sample/sample.html", 
    "controller": "SampleController", 
    "controllerAs": "sampleCtrl", 
    "bindings": { 
     "config": "<", 
     "foobar": "&" 
    } 
}) 
.controller("SampleController", 
      ["$scope", 
    function($scope) { 
     this.isActive = true; 

     this.foo = function() { 
      // do stuff 
      this.isActive = false; 

      // also do 
      this.foobar(); 
     }; 
    } 
); 

Einheit Test

describe("Component: SampleComponent", function() { 

    beforeEach(module("myApp")); 

    var sampleComponent, scope, $httpBackend; 

    beforeEach(inject(function($componentController, $rootScope, _$httpBackend_) { 
     scope = $rootScope.$new(); 
     sampleComponent = $componentController("sample", { 
      "$scope": scope 
     }); 
     $httpBackend = _$httpBackend_; 
    })); 

    it("should do set isActive to false on 'foo' and call method...", function() { 
     spyOn(sampleComponent, "foobar") 

     expect(sampleComponent.isActive).toBe(true); 
     expect(sampleComponent).toBe(""); 
     expect(sampleComponent.foobar).not.toHaveBeenCalled(); 

     sampleComponent.foo(); 

     expect(sampleComponent.foobar).toHaveBeenCalled(); 
     expect(sampleComponent.foobar.calls.count()).toBe(1); 
     expect(sampleComponent.isActive).toBe(false); 
    }); 
}); 

Ich hoffe, dass ich keine Fehler zu dieser hinzugefügt haben, aber das oben ist etwa, was ich versuche zu machen. Irgendwelche Vorschläge sind willkommen und wenn der Ansatz falsch ist oder mehr Informationen benötigt werden, lass es mich wissen!

+1

'$ componentController' ist nur für Test Component-Controller. Sie müssen also der Eigenschaft 'foobar' einen Stub zuweisen. – estus

+0

Ich dachte nur, das könnte funktionieren, weil 'foobar' dem Bereich 'this.foobar()' der Controller zugewiesen wird. @estus was meinst du mit einem Stub? Eine Methode? – skofgar

+1

Ein Stub ist ein leerer Spion, wie 'sampleComponent.foobar = jasmine.createSpy()'. $ componentController ist ein Wrapper für $ controller. Es erstellt nur einen Controller vom definierten Komponenten-Controller und ignoriert alles andere. Um eine Komponente vollständig mit Bindings zu testen, sollte sie mit '$ compile' kompiliert werden und unterscheidet sich in diesem Fall nicht von den Direktiven. – estus

Antwort

1

Nach der Hilfe von @estus (siehe Kommentare in Frage) - Ich habe gelernt, dass ich createSpy verwenden kann, um dieses Problem zu lösen.

it("should do set isActive to false on 'foo' and call method...", function() { 
     sampleComponent.foobar = jasmine.createSpy(); 

     expect(sampleComponent.isActive).toBe(true); 
     expect(sampleComponent).toBe(""); 
     expect(sampleComponent.foobar).not.toHaveBeenCalled(); 

     sampleComponent.foo(); 

     expect(sampleComponent.foobar).toHaveBeenCalled(); 
     expect(sampleComponent.foobar.calls.count()).toBe(1); 
     expect(sampleComponent.isActive).toBe(false); 
    }); 

Einige zusätzliche Quellen, die ich verwendet wurden, waren:

Verwandte Themen