注入模拟成一个AngularJS服务

问题描述:

我有一个服务AngularJS服务书面和想单元测试。

I have an service AngularJS service written and would like to unit test it.

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

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

    return this;
});

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

My app.js file has these registered:

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

我可以测试DI工作这样:

I can test the DI is working as such:

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框架来创建,但是接下来我想单元测试服务,这意味着嘲讽了注入的对象。

This proved that the service can be created by the DI framework, however next I want to unit test the service, which means mocking out the injected objects.

我如何去这样做?

我试过把我的模仿对象的模块,例如英寸

I've tried putting my mock objects in the module, e.g.

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创建所有。服务

But the latter seems to stop the service being created by the DI as all.

有谁知道我可以为我的单元测试嘲笑注射服务?

Does anybody know how I can mock the injected services for my unit tests?

感谢

大卫

您可以通过使用注入嘲笑为您服务 $提供

You can inject mocks into your service by using $provide.

如果你有,有一个方法调用getSomething依赖以下服务:

If you have the following service with a dependency that has a method called getSomething:

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

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

You can inject a mock version of myDependency as follows:

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 你实际上并不需要在任何地方明确的注入myDependency。它为myService的注射过程中发生的引擎盖下。当这里设置mockDependency,它可以很容易被间谍。

Note that because of the call to $provide.value you don't actually need to explicitly inject myDependency anywhere. It happens under the hood during the injection of myService. When setting up mockDependency here, it could just as easily be a spy.

感谢 loyalBrown ,在链接的这个伟大的影片