javascript - 将模拟注入(inject) AngularJS 服务

标签 javascript angularjs mocking jasmine angularjs-service

我编写了一个 AngularJS 服务,我想对其进行单元测试。

angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
    factory('myService', function ($http, fooService, barService) {

    this.something = function() {
        // Do something with the injected services
    };

    return this;
});

我的 app.js 文件注册了这些:

angular
.module('myApp', ['fooServiceProvider','barServiceProvider','myServiceProvider']
)

我可以测试 DI 是否正常工作:

describe("Using the DI framework", function() {
    beforeEach(module('fooServiceProvider'));
    beforeEach(module('barServiceProvider'));
    beforeEach(module('myServiceProvder'));

    var service;

    beforeEach(inject(function(fooService, barService, myService) {
        service=myService;
    }));

    it("can be instantiated", function() {
        expect(service).not.toBeNull();
    });
});

这证明服务可以由 DI 框架创建,但是接下来我想对服务进行单元测试,这意味着模拟注入(inject)的对象。

我该怎么做?

我试过将我的模拟对象放入模块中,例如

beforeEach(module(mockNavigationService));

并将服务定义重写为:

function MyService(http, fooService, barService) {
    this.somthing = function() {
        // Do something with the injected services
    };
});

angular.module('myServiceProvider', ['fooServiceProvider', 'barServiceProvider']).
    factory('myService', function ($http, fooService, barService) { return new MyService($http, fooService, barService); })

但后者似乎完全停止了 DI 创建的服务。

有人知道我如何为我的单元测试模拟注入(inject)的服务吗?

谢谢

大卫

最佳答案

您可以使用 $provide 将模拟注入(inject)您的服务。

如果您有以下服务,其依赖项具有名为 getSomething 的方法:

angular.module('myModule', [])
  .factory('myService', function (myDependency) {
        return {
            useDependency: function () {
                return myDependency.getSomething();
            }
        };
  });

您可以按如下方式注入(inject) myDependency 的模拟版本:

describe('Service: myService', function () {

  var mockDependency;

  beforeEach(module('myModule'));

  beforeEach(function () {

      mockDependency = {
          getSomething: function () {
              return 'mockReturnValue';
          }
      };

      module(function ($provide) {
          $provide.value('myDependency', mockDependency);
      });

  });

  it('should return value from mock dependency', inject(function (myService) {
      expect(myService.useDependency()).toBe('mockReturnValue');
  }));

});

请注意,由于调用了 $provide.value,您实际上不需要在任何地方显式注入(inject) myDependency。它发生在注入(inject) myService 期间。在这里设置 mockDependency 时,它很容易成为 spy 。

感谢loyalBrown链接到 that great video .

关于javascript - 将模拟注入(inject) AngularJS 服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14773269/

相关文章:

Hadoop 迷你集群模拟 (MiniDFSCluster)

typescript - 在 Jest 和 typescript 中模拟交叉点观察者

javascript - React BrowserRouter - 如何以编程方式导航到不同的路线?

javascript - .diff 不是 Moment.js 中的函数

javascript - 如何检查 Angular 1.5 中是否存在组件

javascript - 如何从 angularjs 中的 Controller CandidateCtrl.js 访问 Data.js 的功能?

javascript - 评估自定义指令内的表达式

javascript - 如何强制 Chrome/Firefox/Opera 从本地主机执行跨域请求?

javascript - 更新指令的模板 AngularJS

jsf-2 - 如何在junit中使用OmniFaces