使用angular-text-patterns测试带有$resource和$promise的angular控制器



我遵循angular-test-patterns指南,并在我的第一个控制器测试中使其工作。但是当我编写下一个测试时,我得到了错误:

TypeError: 'undefined'不是一个对象(求值'$scope.pages.$promise')

我知道问题是下面这行:

美元范围。

<scope.pages.$promise;>

但我不知道如何处理这个,特别是因为我是非常新的测试问题与JavaScript。我在寻找一种正确可行的方法来做这件事,给我指明正确的方向。

控制器:

angular.module('webvisor')
    .controller('page-list-controller', function($scope,Page){
        $scope.pages = Page.query();
        $scope.busy = $scope.pages.$promise;
    });

服务:

angular.module('webvisor').
    factory('Page', ['$resource', 'apiRoot', function($resource, apiRoot) {
        var apiUrl = apiRoot + 'pages/:id/:action/#';
        return $resource(apiUrl,
            {id: '@id'},
            {update: {method: 'PUT'}}
        );
    }]);

测试:

'use strict';
describe('Controller: page-list-controller', function () {
    var ctrl, scope, rootScope, Page;
    beforeEach(function () {
        module('webvisor');
        module(function ($provide) {
            $provide.value('Page', new MockPage());
        });
        inject(function ($controller, _Page_) {
            scope = {};
            rootScope = {};
            Page = _Page_;
            ctrl = $controller('page-list-controller', {
                $scope: scope,
                $rootScope: rootScope
            });
        });
    });
    it('should exist', function () {
        expect(!!ctrl).toBe(true);
    });
    describe('when created', function () {
        // Add specs
    });
});

模拟:

MockPage = function () {
    'use strict';
    // Methods
    this.query = jasmine.createSpy('query'); // I dont know if this is correct
    return this;
};

使用Mox,您的解决方案看起来像这样:

describe('Controller: page-list-controller', function () {
  var mockedPages = []; // This can be anything
  beforeEach(function () {
    mox
    .module('webvisor')
    .mockServices('Page') // Mock the Page service instead of $httpBackend!
    .setupResults(function () {
      return {
        Page: { query: resourceResult(mockedPages) }
      };
    })
    .run();
    createScope();
    createController('page-list-controller');
  });
  it('should get the pages', function () {
    expect(this.$scope.pages).toEqual(resourceResult(mockedPages));
  });
});

正如你所看到的,Mox已经抽象掉了所有的样板注入,比如$rootScope$controller。此外,还支持开箱即用的测试资源和承诺。

改进

我建议您不要将资源结果直接放在作用域上,而是将其解析为承诺:

$scope.busy = true;
Pages.query().$promise
  .then(function (pages) {
    $scope.pages = pages;
    $scope.busy = false;
  });

Mox测试是这样的:

expect(this.$scope.busy).toBe(true);
this.$scope.$digest(); // Resolve the promise
expect(this.$scope.pages).toBe(mockedPages);
expect(this.$scope.busy).toBe(false);

注意:您也可以将createScope()的结果存储到$scope变量中并在任何地方重用,而不是访问this.$scope

经过一些研究和许多尝试和错误案例后,我用一个可能的解决方案回答自己,但我希望很快找到一些更可用且不太重复的解决方案。现在,我对此很满意,使用$httpBackend

测试:

'use strict';
describe('Controller: page-list-controller', function () {
    var ctrl, scope, rootScope, httpBackend, url;
    beforeEach(function () {
        module('webvisor');
        inject(function ($controller, $httpBackend, apiRoot) {
            scope = {};
            rootScope = {};
            httpBackend = $httpBackend;
            url = apiRoot + 'pages/#';
            ctrl = $controller('page-list-controller', {
                $scope: scope,
                $rootScope: rootScope
            });
        });
    });
    it('should exist', function () {
        expect(!!ctrl).toBe(true);
    });
    describe('when created', function () {
        it('should get pages', function () {
            var response = [{ 'name': 'Page1' }, { 'name': 'Page2' }];
            httpBackend.expectGET(url).respond(200, response);
            httpBackend.flush();
            expect(scope.pages.length).toBe(2);
        });
    });
});

我在阅读这个问题时找到了这个解决方案。这工作得很好,现在,我很满意。在以后,我尝试了一些类似的东西:

  • angular-easy-test
  • 混合氧化物燃料

相关内容

  • 没有找到相关文章

最新更新