javascript - 将模拟提供者注入(inject) Angular 单元测试

标签 javascript angularjs unit-testing

我正在尝试找出如何模拟单元测试的 Angular 提供程序。在下面的代码片段中,我有一个“翻译”提供程序,用于确定默认情况下在 View 中显示哪种语言。我想在我的测试中注入(inject)该提供程序的不同版本,以确保我的应用程序根据提供程序的设置显示正确的内容。我现在所做的显然不起作用。预先感谢您的帮助。

顺便说一句,如果您想知道为什么使用提供程序而不是使用服务或简单值等其他内容,这是一个人为的示例,它提炼了我在大型应用程序中遇到的问题。我需要将一些内容注入(inject)到应用程序的配置方法中,这意味着我需要模拟提供程序。

var app = angular.module('app', []);
app.config(function($provide) {
  $provide.provider('translate', function() {
    return {
      $get: function() {
        return {
          language: 'en'
        };
      }
    };
  });
});
app.controller('ctl', function($scope, translate) {
  if (translate.language === 'en') {
    $scope.greeting = "Welcome to the application.";
  } else {
    $scope.greeting = "Velkommen til appen.";
  }
});

// ---SPECS-------------------------
describe('App', function() {
  beforeEach(angular.mock.module('app'));

  describe('by default', function() {
    beforeEach(angular.mock.inject(
      function(_$compile_, _$rootScope_) {
        const viewHtml = $('#view');
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        $rootScope.isOn = false;
        elm = $(viewHtml);
        $compile(elm)($rootScope);
        $rootScope.$digest();
      }));
    it('shows English', function() {
      expect(elm.text()).toMatch(/Welcome/);
    });
  });

  describe('without English specified', function() {
    beforeEach(angular.mock.module('app', function ($provide) {
      $provide.provider('translate', function () {
        return {
          $get: function () {
            return { preferredLanguage: 'no' };
          }
        };
      });
    }));
    beforeEach(angular.mock.inject(
      function(_$compile_, _$rootScope_) {
        const viewHtml = $('#view');
        $compile = _$compile_;
        $rootScope = _$rootScope_;
        $rootScope.isOn = false;
        elm = $(viewHtml);
        $compile(elm)($rootScope);
        $rootScope.$digest();
      }));
    it('shows Norwegian', function() {
      expect(elm.text()).toMatch(/Velkommen/);
    });
  });

});

// --- Runner -------------------------
(function() {
  var jasmineEnv = jasmine.getEnv();
  jasmineEnv.updateInterval = 1000;
  var htmlReporter = new jasmine.HtmlReporter();
  jasmineEnv.addReporter(htmlReporter);
  jasmineEnv.specFilter = function(spec) {
    return htmlReporter.specFilter(spec);
  };
  var currentWindowOnload = window.onload;
  window.onload = function() {
    if (currentWindowOnload) {
      currentWindowOnload();
    }
    execJasmine();
  };

  function execJasmine() {
    jasmineEnv.execute();
  }
})();
<link href="http://jasmine.github.io/1.3/lib/jasmine.css" rel="stylesheet"/>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="http://code.angularjs.org/1.4.9/angular.js"></script>
<script src="http://code.angularjs.org/1.4.9/angular-mocks.js"></script>
<script src="http://jasmine.github.io/1.3/lib/jasmine.js"></script>
<script src="http://jasmine.github.io/1.3/lib/jasmine-html.js"></script>
<div ng-app="app">
  <div id="view" ng-controller="ctl">{{greeting}}</div>
</div>

最佳答案

你可以这样做:-

  beforeEach(module('app', function ($provide) {
         $provide.provider('translate', function() {
          return {
            $get: function() {
              return {
                language: 'fr'
              };
            }
          };
        });
    }));

您还可以将上述代码放在 util 方法中,该方法会将语言代码作为参数,这样您就不会将上述代码传播到各处。

关于javascript - 将模拟提供者注入(inject) Angular 单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35068624/

相关文章:

javascript - 在 body 标签上使用 ng-view 有什么缺点吗?

javascript - 如何使用 $routeProvider 的解析参数显式声明注入(inject)器?

unit-testing - 类似于 Spock 的 "@Unroll"的 JUnit 理论?

java - 如何从 JMockit 模拟静态方法

Java 注释处理器 - 带注释的 Kotlin 类单元测试

javascript - 如何在ReactJS中通过ref动态设置State

javascript - jquery 遍历 DOM 树

javascript - 如何取消/忽略 redux 中的操作

javascript - 将变量绑定(bind)到 Angular Js 中的已编译元素

javascript - 欧芹表单验证错误