Angularjs 测试服务内部调用指令

Angularjs 测试服务内部调用指令,angularjs,Angularjs,我有以下服务和指令: angular.module("epcApp", []) .service("epcData", function($http, $q){ var urls = { load: "some-url", save: "some-url" }; this.load = function(){ return $http.get(urls.load).then(function(data){

我有以下服务和指令:

angular.module("epcApp", [])
.service("epcData", function($http, $q){
    var urls = {
        load: "some-url",
        save: "some-url"
    };
    this.load = function(){
        return $http.get(urls.load).then(function(data){
            return data;
        });
    }
    this.save = function(req){
        return $http.get(urls.save, req).then(function(data){
            return data;
        });
    }
})
.directive("epc", ['epcData', function(epcData){
    return {
        restrict: "E",
        templateUrl: "some-url",
        link: function(scope, element, args, form){
            scope.collectSelects = function(container){
                // some code
            }

            scope.collectCheckBoxes = function(container){
                // some code
            }

            epcData.load().then(function(data){
                scope.userOptions = 
                // do something with scope.collectCheckBoxes and scope.collectSelects
            });
        }
    }
}]);
我想测试一下:

  • epcData.load是从指令内部调用的
  • collectSelects和CollectCheckBox在epcData.load的承诺内被调用
  • 我不知道该如何模仿这项服务。这是我在文档中看到的:

        //Load the EPC main module
        beforeEach(module('epcApp'));
    
        //Intialize the directive with a mock scope
        beforeEach(function(){
            var element, scope, epcData, $httpBackend, mock;
            mock = {
                load: jasmine.createSpy(),
                save: jasmine.createSpy()
            }
            module(function($provide){
                $provide.service('epcData', mock);
            })
            inject(function($rootScope, $compile, $injector){
                epcData = $injector.get('epcData');
                scope = $rootScope.$new();
                element = angular.element("<epc></epc>");
                element = $compile(element)(scope);
                scope.$digest();
            })
        });
    
        it("should have loaded data", function(){
            expect(mock.load).toHaveBeenCalled();
        })
    
    //加载EPC主模块
    在每个(模块(“epcApp”)之前;
    //使用模拟范围初始化指令
    beforeach(函数(){
    var元素,范围,epcData,$httpBackend,mock;
    模拟={
    加载:jasmine.createSpy(),
    保存:jasmine.createSpy()
    }
    模块(功能($提供){
    $provide.service('epcData',mock);
    })
    注入(函数($rootScope,$compile,$injector){
    epcData=$injector.get('epcData');
    scope=$rootScope.$new();
    元素=角度。元素(“”);
    元素=$compile(元素)(范围);
    范围。$digest();
    })
    });
    它(“应该已加载数据”,函数(){
    expect(mock.load).tohavebeencall();
    })
    
    我得到以下错误
    error:[ng:areq]参数'fn'不是函数,get对象


    如果我同时删除了
    $provide
    $injector
    部分,当实际的
    epcData.load
    方法尝试执行http请求时,我会收到一个“意外请求”错误。因此,我似乎快要重写服务方法了,但我做得不对。

    错误即将出现,因为您需要传递构造函数来创建角度服务。您正在传递一个对象

    您可以使用
    功能代替
    服务

    $provide.value('epcData',mock)

    或者您可以创建一个伪构造函数


    此外,jasmine spy的实现应该返回一个承诺,否则调用函数将失败(否
    然后
    )。请参阅jasmine的文档,并从您的虚拟函数返回
    $q.when()

    我实际上尝试了
    value
    ,但我得到了另一个错误,基本上是我的原始“加载”方法触发,尝试加载原始URL并获取“意外请求”。所以在这种情况下,我似乎无法覆盖我原来的方法。我会调查你推荐的间谍的文件。谢谢。如果您使用value,则不应触发origin load方法,因为它已被此value服务隐藏。