angularjs测试组件中的指令

时间:2017-07-02 22:58:21

标签: javascript angularjs unit-testing jasmine

我正在使用角度js 1.5。我有一个包含电影列表(数组)的组件,并期望使用指令(电影项目)渲染电影列表。

我正在尝试对此组件进行单元测试,并确保它已经渲染了与电影列表数组长度相匹配的电影。

movie-item指令希望收集用户的输入,但我只是简化它。

我该如何测试?

电影列表组件

   (function() {
    "use strict";

    var module = angular.module("psMovies");

    function controller() {
        var model = this;
        model.movies = [];

        model.$onInit = function() {
            model.movies = [{"id": 1,"title": "Star Wars"},{"id": 2,"title": "Star Trek"}];           
        };
    }

    module.component("movieList", {
        templateUrl: "movie-list.component.html",
        controllerAs: "model",
        controller: [ controller]
    });

} ());

movie-list.component html

  <div ng-repeat="movie in model.movies">
        <movie-item item="movie"> </movie-item>
    </div>

电影项目组件

angular.module('psMovies')
    .directive('movieItem', function() {
        "use strict";
        return {
            templateUrl: 'movie-item.component.html',
            restrict: 'EA',
            scope: {
                item: '=', 
            },
            link: function(scope) {

            }
        };
    });

电影项目html

 <div> {{model.id}}  - {{model.title}}</div> 

我的单元测试

describe("The movieList component", function () {

    beforeEach(module("psMovies"));

    var moviesList;
    beforeEach(inject(function ($componentController) {
        moviesList = $componentController("movieList",{
           $scope: {} 
        });
    }));

    it("can be created", function () {
        expect(moviesList).toBeDefined();
        expect(moviesList.$onInit).toBeDefined();
    });

});

1 个答案:

答案 0 :(得分:0)

为了测试组件/指令模板,应该使用$compile编译。

测试这个的方法不止一种。如果嵌套的指令/组件过于复杂,则用伪指令/组件替换它们以进行隔离测试是有意义的,即在movieList测试movieItem中可以进行模拟,只是为了测试它是否正确绑定movieList模板,例如:

describe('movieList tests', () => {
  beforeEach(module('psMovies', ($provide) => {
    $provide.directive('movieItem', () => ({
      scope: { item: '=' }
    }));
  });
  ...
  it('should compile movie items', inject(($rootScope) => {
    let scope = $rootScope.$new();
    const movieList = $compile('<movie-list>')(scope);
    $rootScope.$digest();
    const mockedMovieItems = movieList.find('movie-item');
    expect(mockedMovieItems.length).toBe(2);
    const mockedMovieItem = mockedMovieItems[0];
    expect(mockedMovieItem.isolateScope().item).toEqual({"id": 1,"title": "Star Wars"});
    ...
  }));
});

然后可以单独测试真实movieItem

describe('movieItem tests', () => {
  beforeEach(module('psMovies'));
  ...
  it('should compile movie items', inject(($rootScope) => {
    let scope = $rootScope.$new();
    scope.movie = {"id": 1,"title": "Star Wars"};
    const movieItem = $compile('<movie-item item="movie">')(scope);
    $rootScope.$digest();
    expect(movieItem.isolateScope().item).toEqual({"id": 1,"title": "Star Wars"});
    ...
  }));
});