代码之家  ›  专栏  ›  技术社区  ›  Brian Var

如何在Jasmine单元测试中模拟模块API依赖关系?

  •  0
  • Brian Var  · 技术社区  · 6 年前

    我有一个案例来单元测试自定义角度指令 myApp 并设置了必要的因果报应和茉莉配置。 在这个测试用例中,我尝试模拟和存根 myApp ,这是服务- services.FuzzAPI . 因为我无法使用这些服务。FuzzAPI文件使用sinon对其进行模拟。

    根据Angular和Jasmine文档,我在 .spec 文件并遵循此 similar SO answer

    1. 在第一个beforeach中,根据 this guide 并注册了 myApp 要使用测试的模块 angular.mock.module .
    2. 然后在第二个beforeach中,使用$injector将模拟的FuzzAPI传递给$compile步骤 myApp 指令。

    $injector:modulerr 告诉我这些服务。FuzzAPI不可用。 这告诉我soemthing是一个注册 服务。FuzzAPI 附属国:

     LOG LOG: 'before mock'
     LOG LOG: 'after mock'
     Error: [$injector:modulerr] Failed to instantiate module myApp due to:
            Error: [$injector:modulerr] Failed to instantiate module services.FuzzAPI due to:
            Error: [$injector:nomod] Module 'services.FuzzAPI' is not available! You either misspelled the module name or forgot to load it
    

    问题:

    如何在Jasmine单元测试中模拟指令依赖性?

    查看代码,我可以看到这个错误正在联机抛出 beforeEach(inject(function($rootScope, _$compile_, $injector) { 作为控制台。在注入内记录 beforeEach 在抛出错误之前不会感到疲倦。

    指令和测试规范要点:

    //我的应用程序。js公司

    (function() {
    
      var component = {
        id: "myApp",
        name: "My App",
        templateUrl: localStorage.getItem("baseURL") + "my-app/my-app.html"
      };
    
      component.ui = angular.module("myApp", ["services.FuzzAPI"]);
      component.ui.directive("myApp", widgetComponent);
    
      function widgetComponent(FuzzAPI) {
    
        // main widget container
        function widgetContainer(scope, element, params) {
          var api = new FuzzAPI(params);
    
          scope.greeting = "Hello World";
    
          var setGreeting = function(message){
            scope.greeting = message;  
          };
    
          api.onDataEvent("onFuzzEvent", function(data) {
            scope.greeting = data;
          });
    
    
          element.on("$destroy", function() {     
            api.unregister();
            scope.$destroy();
          });
        }
    
        return {
          scope: {},
          replace: true,
          link: widgetContainer,
          templateUrl: component.templateUrl
        };
      }
    })();
    

    //我的应用程序。规范js

    describe("myApp", function() {
    
      var $scope, $compile, $provide, $injector, element, fuzzAPIMock, FuzzAPIProvider;
    
      beforeEach(function(){
    
        //mock service FuzzAPI via service provider
        fuzzAPIMock = {
          greeting : "123",
          initializeCurrentItem : function () {
            return true;
          }
        };
    
        console.log("before mock");
    
        //register module and mock dependency
        angular.mock.module(function($provide) {
                $provide.value('services.FuzzAPI', fuzzAPIMock);
        });
    
        angular.mock.module("myApp");
    
        console.log("after mock");
    
    
      });
    
      beforeEach(inject(function($rootScope, _$compile_, $injector) {
    
        console.log("in inject..");
        FuzzAPIProvider = $injector.get('services.FuzzAPI');
        $scope = $rootScope.$new(), //create instance of rootScope
        $compile = _$compile_; 
        console.log("in inject before compile..");
        element = $compile("<my-app></my-app>")($scope); // compile attaches directives to HTML template
        console.log("in inject after compile..");
        $scope.$digest(); //loop through DOM watchers, check values and trigger listeners
      }));
    
    
    });
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Estus Flask    6 年前

    错误:[$injector:nomod]模块的服务。FuzzAPI不可用!您要么拼错了模块名称,要么忘记加载它

    意味着它是 services.FuzzAPI 单元 这应该被嘲笑,而不是 服务 . 根据提供的代码,服务名称为 FuzzAPI ,应该用 对象 .

    为了使丢失的模块不会导致错误,应将其存根。它可以在顶层进行一次存根 describe 块:

    beforeAll(() => {
      angular.module('services.FuzzAPI', []);
    });
    

    恢复存根模块是不可能的(至少在没有黑客的情况下是不可能的),但如果真实的模块不应该出现在测试中,这也不是问题。

    然后服务可以像往常一样被嘲笑。如果是 FuzzAPI :,应该是

    fuzzAPIMock = jasmine.createSpy('').and.returnValue({
      greeting : "123",
      initializeCurrentItem : jasmine.createSpy('').and.returnValue(true)
    });
    
    angular.mock.module(function($provide) {
      $provide.value('FuzzAPI', fuzzAPIMock);
    });
    

    最好使用Jasmine间谍作为模拟/存根函数。