2016-11-16 2 views
3

Привет, сообщество stackoverflow.Как выполнить модульное тестирование функции в компоненте, который вызывает метод для родительского компонента

Я работаю над угловым проектом (1.5.6), используя компонентную структуру и в настоящее время пишу некоторые отдельные тесты. Я все еще многому разбираюсь в модульных тестах, особенно в отношении Angular, и надеялся, что я могу попросить вас о помощи в следующем выпуске:

Я пытаюсь протестировать компонент, который получает метод обратного вызова из его родительского компонента , Я пытаюсь высмеять метод foo (см. Пример кода). И к сожалению этот метод вызывает родительский контроллер.

Поэтому, когда я пытаюсь его протестировать, он жалуется, что метод не определен. Тогда я подумал, что могу издеваться над ним с помощью spyOn, но потом я получаю ошибку Error: <spyOn> : foobar() method does not exist

Так что я думаю, что не могу издеваться над этим методом.

Модуль:

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

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

Я надеюсь, что я не добавлял никаких ошибок в этом, но это выше примерно то, что я пытаюсь делать. Любые предложения приветствуются, и если подход неправильный или требуется больше информации, пожалуйста, дайте мне знать!

+1

'$ componentController' предназначен только для контроллера компонентов тестирования. Поэтому вам нужно назначить заглушку для свойства foobar. – estus

+0

Я просто подумал, что это может сработать, потому что 'foobar' присваивается области управления' this.foobar() '. @estus, что вы имеете в виду с заглушкой? Метод? – skofgar

+1

Штук - это пустой шпион, например 'sampleComponent.foobar = jasmine.createSpy()'. $ componentController - это оболочка для $ controller. Он просто создает контроллер из определенного контроллера компонентов и игнорирует все остальное. Чтобы полностью протестировать компонент с привязками, он должен быть скомпилирован с '$ compile' и т. Д., В этом случае он не отличается от директив. – estus

ответ

1

После помощи @estus (см. Комментарии) - Я узнал, что могу использовать createSpy для решения этой проблемы.

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

Некоторые дополнительные источники, которые я использовал были:

Смежные вопросы