如何在指令的链接中监视服务函数



我有一个使用如下服务函数的指令:

angular.module('testModule',
['serviceBeingUsed'])
.directive('testDirective', function(serviceBeingUsed) {
    return {
        restrict: 'AE',
        templateUrl: 'testTemplate.tpl.html',
        scope: {
            boundVar1: "="
        },
        link: function(scope) {
            scope.getRequiredData = function(data){
                //gether data using service
                serviceBeingUsed.fetchRequiredData(data).then(
                    function(result){
                        scope.requiredData = result;
                    }
                );
            };
        }
    };
});

在上面的指令中,我注入了我想要使用的服务,这个服务函数在该指令的"link"内部的作用域函数"getRequiredData()"中使用。

我有我的测试套件设置如下:

describe('test suite', function () {
var scope,
    $rootScope,
    $compile,
    $q,
    element,
    isoScope,
    serviceBeingUsed;
beforeEach(module('testModule'));
beforeEach( inject( function(_$rootScope_,
                             _$q_,
                             _$compile_,
                             _serviceBeingUsed_) {
    $rootScope = _$rootScope_;
    $compile = _$compile_;
    serviceBeingUsed = _serviceBeingUsed_;
    $q = _$q_;
    //This is where we create the directive and it's options.
    element = angular.element('<test-directive bound-var1="blabla"></test-directive>');
    //We create a new scope from the rootScope.
    scope = $rootScope.$new();
    //Now we compile the HTML with the rootscope
    $compile(element)(scope);
    //digest the changes
    scope.$digest();
    //We retrieve the isolated scope scope of the directive 
    isoScope = element.isolateScope();
}));

现在我有一个运行并通过的测试,我可以在孤立的作用域函数"getRequiredData()"中窥探,这个测试看起来像这样:

it('getRequiredData runs', inject(function () {
    spyOn(isoScope,"getRequiredData");
    isoScope.getRequiredData();
    expect(isoScope.getRequiredData).toHaveBeenCalled();
}));

这证明了链接函数可以被测试,但是当试图测试服务函数是否被调用时,测试失败了,我不知道为什么,服务的测试看起来像这样:

it('serviceFunction runs', inject(function () {
    spyOn(serviceBeingUsed, "serviceFunction").and.callFake(function() {
        var deferred = $q.defer();
        var data = "returnedDataDummy";
        deferred.resolve(data);
        return deferred.promise;
    });
    isoScope.getRequiredData();
    expect(serviceBeingUsed.serviceFunction).toHaveBeenCalled();
}));

如果在这里调用了业务功能,如何成功测试?

通过写这个例子,我已经解决了我的问题。在我的实际代码中,在测试"serviceFunction runs"中,我还包含了一个spyOn(isoScope,"getRequiredData)"

这会阻塞函数

的内部功能。
getRequiredData()

这意味着getRequiredData中的service函数永远不能运行。

为了解决这个问题,我需要编辑外部函数的间谍

来自:

spyOn(isoScope,"getRequiredData");

:

spyOn(isoScope,"getRequiredData").and.callThrough();

这个简单的更改意味着被监视的函数也将运行其内部代码,而不仅仅是注册它已被调用。

然而,我学到的一个重要的教训是不要在每次考试中做太多的事情,并且尽可能地将考试分开。

所以为了澄清,我的原始测试失败了看起来像这样:

it('getRequiredData runs', inject(function () {
    spyOn(serviceBeingUsed, "serviceFunction").and.callFake(function() {
        var deferred = $q.defer();
        var data = "returnedDataDummy";
        deferred.resolve(data);
        return deferred.promise;
    });
    spyOn(isoScope,"getRequiredData");
    isoScope.getRequiredData();
    expect(serviceBeingUsed.fetchRequiredData).toHaveBeenCalled();
    expect(isoScope.getRequiredData).toHaveBeenCalled();
}));

it('getRequiredData runs', inject(function () {
        spyOn(serviceBeingUsed, "serviceFunction").and.callFake(function() {
            var deferred = $q.defer();
            var data = "returnedDataDummy";
            deferred.resolve(data);
            return deferred.promise;
        });
        spyOn(isoScope,"getRequiredData").and.callThrough();
        isoScope.getRequiredData();
        expect(serviceBeingUsed.fetchRequiredData).toHaveBeenCalled();
        expect(isoScope.getRequiredData).toHaveBeenCalled();
    }));

相关内容

  • 没有找到相关文章

最新更新