web-dev-qa-db-ja.com

依存関係があるAngularJSファクトリーのユニットテスト

Angularファクトリー(Karma + Jasmineを使用)のユニットテストを行う場合、テスト対象のファクトリーにスタブ依存関係を挿入するにはどうすればよいですか?

私の工場は次のとおりです。

mod = angular.module('myFactoryMod', []);

mod.factory('myFactory', [
  '$log', 'oneOfMyOtherServices', function($log, svc) {
    return makeSomethingThatDoesSomethingWithTheseDependencies($log, svc);
  }
]);

oneOfMyOtherServicesは、工場をインスタンス化するときに必要です。

私のテストは次のとおりです。

it('can get an instance of my factory', function() {
  var oneOfMyOtherServicesStub;

  angular.mock.module('myFactoryMod');

  oneOfMyOtherServicesStub = {
    someVariable: 1
  };

  //****How do I get my stub in my target? ****

  angular.mock.inject(['myFactory', function(target) {

      expect(target).toBeDefined();

    }
  ]);
})

N.B. $controllerがコントローラーに対してこれを許可していることは知っていますが、工場に対しては同等のものは見当たりません。

76
Roy Truelove

私が知っているこのようなことを達成する2つの方法があります:

  1. $provideと匿名モジュールを使用して、モックを注入します。
  2. モックしたいサービスを注入し、ジャスミンのスパイ機能を使用してモック値を提供します。

2番目のオプションは、テスト対象のコードが挿入されたサービスで呼び出すメソッドを正確に知っている場合にのみ機能し、簡単にモックアウトできます。 (メソッドではなく)サービスのデータプロパティにアクセスしているように見えるので、最初のオプションを追求するのが最適です。

$provideを使用すると、おおよそ次のようになります。

describe('myFactory', function () {
  // Load your module.
  beforeEach(module('myFactoryMod'));

  // Setup the mock service in an anonymous module.
  beforeEach(module(function ($provide) {
    $provide.value('oneOfMyOtherServicesStub', {
        someVariable: 1
    });
  }));

  it('can get an instance of my factory', inject(function(myFactory) {
    expect(myFactory).toBeDefined();
  }));
});
91
Noah Freitas

@bentsaiによるコメントは、実際にはサービスのテストに非常に役立ちます。完全を期すために、例を追加しています。

jasmineのテストは、おおよそ探していることを実行します。注:これには、angular-mocksを含める必要があります(これはmoduleinjectなどの機能を提供するものです)。

describe('app: myApp', function() {
  beforeEach(module('myApp'));
  var $controller;
  beforeEach(inject(function(_$controller_) {
    $controller = _$controller_;
  }));
  // Factory of interest is called MyFactory
  describe('factory: MyFactory', function() {
    var factory = null;
    beforeEach(inject(function(MyFactory) {
      factory = MyFactory;
    }))
    it('Should define methods', function() {
      expect(factory.beAwesome).toBeDefined()
      expect(factory.beAwesome).toEqual(jasmine.any(Function))
    });
  });
});

これは、モジュールと関連するファクトリー定義がどのように見えるかのスタブです。

var app = angular.module('myApp', []);
app.factory('MyFactory', function() {
  var factory = {};
  factory.beAwesome = function() {
    return 'Awesome!';
  }
  return factory;
});

この場合、inject()を使用すると、通常のangularアプリケーションで予想されるように、依存関係を取り込むことができます。したがって、テストをサポートするための要件を構築できます。それらに依存するもの。

12
AJ.