【问题标题】:How to mockout servicecall in jasmine test?如何在茉莉花测试中模拟服务调用?
【发布时间】:2016-02-27 23:34:34
【问题描述】:

我创建了一个 Angular 自定义指令,其中包含一个名为 scriptingService 的服务。目标是使用 spyOn 模拟服务调用。这是测试的一部分:

 beforeEach(inject(function ($rootScope, $compile,_scriptingService_) {
      scope = $rootScope.$new();
      scope.row = 1;

      scriptingService = _scriptingService_;
      Restangular = _Restangular_;

      spyOn(Restangular, 'all').and.callThrough();

      spyOn(scriptingService, 'getScript').and.callThrough();

      element = angular.element('<ul id="rows" ui-list="row">');
      $compile(element)(scope);
      scope.$digest();
    }));

这是指令代码:

.directive('uiList', [
    function(scriptingService) {
        return {
            scope: {
                lengthModel: '=uiList'
            },
            link: function(scope, elm, attrs) {
                scope.$watch('lengthModel', function(newVal) {
                    scope.test=2;
                    console.log('kut');

                    scriptingService.getScript(request).then(function(scripts){
                        scope.scripts = scripts;
                    });

                });
            }
        };
    }
]);

但是我得到一个错误:

RestangularProvider <- Restangular <- scriptingService

如何模拟 scriptingService 并确保调用了该方法? Plunker ref:http://plnkr.co/edit/CDc7EV?p=preview

【问题讨论】:

  • 您的 plunkr 有一些问题:旧 jasmin 版本与新语法相结合,and.callThrough() 在 1.3.1 中不起作用(更新 jasmin 或使用 andCallThrough())并且您的 scriptingService 不起作用t 存在于 plunkr 中。 plunkr 上的错误“Unknown Provider”是预期的,因为没有向模块注册此类服务。
  • 我更新了 plunkr 并添加了 scriptService。我模拟了 Restangular 但仍然收到错误:错误:未知提供者:RestangularProvider
  • 我在plnkr.co/edit/uhyzg6?p=preview看不到它
  • 抱歉刚刚更新了链接:plnkr.co/edit/CDc7EV?p=preview
  • 在我看来,提供的脚本不是一个好的单元测试,你是在测试指令编译吗?您需要模拟其他所有内容,包括restangular。您不需要callThrough...您需要使用预期的数据来响应假...这是为了避免在您的服务出现错误时测试失败。

标签: angularjs angularjs-directive karma-jasmine spy


【解决方案1】:

这里有几个问题:

  1. 就像上面的评论,你需要使用更新版本的茉莉花来实现callThrough的功能,而且Restangular需要下划线,所以你的html文件中也需要引用。

  2. 此外,需要为您的指令修复依赖注入,因为它无法正确注入scriptingService,这永远不允许它调用scriptingService.getScript,因为scriptingServiceundefined。问题是

    [ function(scriptingService) {}]
    

    无法将scriptingService 注入uiList。它只是最终成为undefined

    必须是

    ['scriptingService', function(scriptingService) {}]
    

    function(scriptingService) {}
    

    供参考:https://docs.angularjs.org/guide/di#dependency-annotation

  3. request 在此代码中使用时从未定义过,我不确定它应该是什么。

    scriptingService.getScript(request).then(function(scripts) {
     scope.scripts = scripts;
    });
    
  4. 修复这些问题后,测试仍然失败,提示错误:意外请求:GET /scripting。

    我能够通过在测试中注入$httpBackend(这是一种以角度模拟http调用的服务)并期待一个请求来解决这个问题。所以我改变了

    inject(function ($rootScope, $compile,_scriptingService_,_Restangular_)
    

    inject(function ($rootScope, $compile,_scriptingService_,_Restangular_, $httpBackend)
    

    并添加了这个

    $httpBackend.expectGET("/scripting").respond([]);
    

    spyOn 之后,测试通过了。我不确定这个 http 调用到底应该返回什么,但这只是你如何测试它的一个例子。

    供参考:https://docs.angularjs.org/api/ngMock/service/$httpBackend

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 2015-08-11
    • 2015-08-25
    • 2018-12-17
    • 1970-01-01
    相关资源
    最近更新 更多