21

モジュールの構成関数に提供される注入された定数をオーバーライドしようとすることに対して、私はかなりの時間を費やしてきました。私のコードは次のようになります

common.constant('I18n', <provided by server, comes up as undefined in tests>);
common.config(['I18n', function(I18n) {
  console.log("common I18n " + I18n)
}]);

単体テストで I18n が挿入されていることを保証する通常の方法は、次のようにすることです。

module(function($provide) {
  $provide.constant('I18n', <mocks>);
});

$provideこれは私のコントローラーでは問題なく動作しますが、config 関数はモジュールの外側にあるものを見ていないようです。モックされた値を取得する代わりに、モジュールの一部として定義された以前の値を取得します。(私たちのテストの場合は未定義です。以下のプランカーでは「foo」です。)

動作中のプランカーが下にあります (コンソールを見てください)。誰かが私が間違っていることを知っていますか?

http://plnkr.co/edit/utCuGmdRnFRUBKGqk2sD

4

5 に答える 5

26

まず第一に、plunkr で jasmine が正しく動作していないようです。しかし、私にはよくわかりません。他の誰かがこれをもう一度確認できるかもしれません。それにもかかわらず、新しい plunkr ( http://plnkr.co/edit/MkUjSLIyWbj5A2Vy6h61?p=preview ) を作成し、次の指示に従いました: https://github.com/searls/jasmine-all

beforeEachコードが実行されないことがわかります。これを確認できます:

module(function($provide) {
  console.log('you will never see this');
  $provide.constant('I18n', { FOO: "bar"});
});

次の 2 つが必要です。

  1. 関数の実際のテストitexpect(true).toBe(true)十分です

  2. injectテストのどこかで使用する必要があります。そうしないと、提供された関数moduleが呼び出されず、定数が設定されません。

このコードを実行すると、「緑」が表示されます。

var common = angular.module('common', []);

common.constant('I18n', 'foo');
common.config(['I18n', function(I18n) {
  console.log("common I18n " + I18n)
}]);

var app = angular.module('plunker', ['common']);
app.config(['I18n', function(I18n) {
  console.log("plunker I18n " + I18n)
}]);

describe('tests', function() {

  beforeEach(module('common'));
  beforeEach(function() {
    module(function($provide) {
      console.log('change to bar');
      $provide.constant('I18n', 'bar');
    });
  });
  beforeEach(module('plunker'));    

  it('anything looks great', inject(function($injector) {
      var i18n = $injector.get('I18n');
      expect(i18n).toBe('bar');
  }));
});

ご期待どおりに動作することを願っています!

于 2014-01-10T21:12:19.057 に答える
5

基本的な問題は、構成ブロックの直前に定数を定義しているため、モジュールがロードされるたびに、存在する可能性のあるモック値がオーバーライドされることだと思います。私の提案は、定数と構成を別々のモジュールに分離することです。

于 2014-11-12T00:09:52.397 に答える
3

モジュール定義をオーバーライドできます。もう1つのバリエーションとしてこれを投げ出しています。

angular.module('config', []).constant('x', 'NORMAL CONSTANT');

// Use or load this module when testing
angular.module('config', []).constant('x', 'TESTING CONSTANT');


angular.module('common', ['config']).config(function(x){
   // x = 'TESTING CONSTANT';
});

モジュールを再定義すると、以前に定義されたモジュールが消去され、多くの場合偶然に行われますが、このシナリオでは有利に使用できます (そのようにパッケージ化したい場合)。そのモジュールで定義されている他のものも消去されることを覚えておいてください。そのため、おそらく定数のみのモジュールにしたいと思うでしょう。これはやり過ぎかもしれません。

于 2014-11-09T07:33:22.517 に答える