testing - 如何在指令链接中监视服务功能?

标签 testing service angularjs-directive jasmine angularjs-service

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

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;
                    }
                );
            };
        }
    };
});

在上面的指令中,我注入(inject)了我希望使用的服务,并且该服务函数在该指令“链接”内的作用域函数“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 中的服务函数永远无法运行。

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

来自:

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();
    }));

关于testing - 如何在指令链接中监视服务功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30707925/

相关文章:

performance - 自动防止性能下降

c++ - 来自同一可执行文件的多个服务

AngularJS - 在更改模型值的指令中,为什么我必须调用 $render?

javascript - 只使用一次 Angular Directive(指令)

javascript - 我的 AngularJS Spinner 指令失败

unit-testing - 如何对 Groovy 脚本进行单元测试,在 Elasticsearch 中用于 _score 计算

java - 如何模拟 JodaTime 实际日期?

java - Spock 中 TestNG 数据提供者的模拟

c# - 使用 C# ServiceController 和模拟启动/停止 Windows 服务

Android:应用程序重新启动时如何检测后台服务?