使用实际服务模拟来自控制器的服务调用Jasmine

时间:2015-08-19 16:06:22

标签: angularjs jasmine

我试图测试使用Spy和mock从控制器调用服务。 Jasmine的错误似乎是它试图调用实际服务?我做错了什么?

控制器

angular.module('vsApp').controller('kitsCtrl', function ($scope, productsDataService) {

    productsDataService.getProducts("kit").success(function (data) {

        $scope.products = data;

    });

});

规格

describe("Kits controller", function () {

    var productsDataServiceMock, $controllerConstructor, scope;

    beforeEach(module('vsApp'));

    beforeEach(inject(function ($controller, $rootScope) {

        $controllerConstructor = $controller;
        scope = $rootScope.$new();
        productsDataServiceMock = {

            getProducts: function(type) {return {};}
        };

    }));

    it('should call the products data service', inject(function () {

        var ctrl = $controllerConstructor('kitsCtrl', {$scope: scope, productsDataService: productsDataServiceMock});

        spyOn(productsDataServiceMock, 'getProducts').andCallThrough();

        expect(productsDataServiceMock.getProducts).toHaveBeenCalled();

    }));

});

错误

TypeError: 'undefined' is not a function (evaluating 'productsDataService.getProducts("kit").success(function (data) {

            $scope.products = data;

        })')
        at /**removed**/public/app/controllers/kitsCtrl.js:9

1 个答案:

答案 0 :(得分:0)

测试中有两个错误:

  1. 在构建控制器之后监视模拟,因此在控制器调用了模拟之后。
  2. 控制器期望服务返回具有success()方法的对象,但是mock会返回一个空对象。因此,在调用success()时,由于该方法不存在,因此抛出异常。
  3. 我的建议:不要创建模拟。窥探真实服务,并使用真正的promise API,而不是即将被弃用的成功/错误回调:

    angular.module('vsApp').controller('kitsCtrl', function ($scope, productsDataService) {
    
        productsDataService.getProducts("kit").then(function (data) {
            $scope.products = data;
        });
    });
    

    var $controller;
    
    beforeEach(inject(function (_$controller_, $rootScope) {
    
        scope = $rootScope.$new();
        $controller = _$controller_;
    }));
    
    it('should call the products data service', inject(function(productsDataService, $q) {
        spyOn(productsDataService, 'getProducts').andReturn($q.when('someData'));
        $controller('kitsCtrl', {$scope: scope});
    
        expect(productsDataServiceMock.getProducts).toHaveBeenCalledWith('kit');
        expect($scope.products).toBe('someData');
    }));