1. ホーム
  2. javascript

[解決済み] AngularJSのサービスにモックをインジェクションする

2022-09-07 01:08:40

質問

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フレームワークでサービスを作成できることが証明されましたが、次にサービスをユニットテストしたいのですが、これは注入されたオブジェクトをモック化することを意味します。

どのようにすればよいのでしょうか?

モジュール内にモックオブジェクトを配置してみました。

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によって作成されるサービスをすべて停止してしまうようです。

誰か、私のユニットテストのために注入されたサービスをモック化する方法を知っていますか?

ありがとうございます。

デビッド

どのように解決するのですか?

モックをサービスに注入するためには $provide .

getSomethingというメソッドを持つ以下のようなサービスを依存関係で持っている場合。

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

以下のようにすれば、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 を呼び出すため、実際にはどこにも明示的に myDependency を注入する必要がないことに注意してください。これは myService のインジェクションの際に、フードの下で行われます。ここで mockDependency を設定する場合、それは単にスパイである可能性もあります。

おかげさまで ロイヤルブラウン へのリンクに感謝します。 その素晴らしいビデオ .