1

私はhttp://misko.hevery.com/attachments/Guide-Writing%20Testable%20Code.pdf (特にページ 8 を参照) を読んで、テスト可能なコードの記述に関する Misko の Youtube ビデオを見ていましたが、Angular DI はデメテルの法則を破るように強制しますか。

Demeter の法則を破る Java コンストラクターの例を PDF から単純化すると、次のようになります。

class AccountView {
  boolean isAdmin;
  AccountView(AccountService) {
    isAdmin = AccountService.getCurrentUser().getProfile().isAdmin();
  }
}

このクラスは、ユーザーが管理者であるかどうかのみを必要とし、AccountService は必要としないためです。

Angularは、DIでDemeterの法則を破るように強制しているようです。次の代替手段が見つかりません。

.controller('AccountServiceController', 
  ['AccountService', 
  function(AccountService) {
    this.user = AccountService.getCurrentUser().getProfile().isAdmin();
  }]
);

これが解決パラメーターを持つルーターのコントローラーであるコントローラーである場合、ユーザーを注入できますが、一般的なケースではできません。何かご意見は?AccountService のみがシングルトンであり、後続の各オブジェクトはインスタンスである (DI できない) と想定していることに注意してください。

4

1 に答える 1

1

あなたが提供したAngularの例、またはAngular DIが一般的にデメテルの法則を破っているのかどうかはわかりません。Angular 依存性注入を使用すると、非常にテストしやすいコードを作成できます。

AccountService.getCurrentUser();realが非常に高価なネットワーク操作であると仮定しましょう。テストでこのメソッドを呼び出したくありません。Angular の依存性注入を使用すると、モックを作成できるAccountServiceため、実際のものを呼び出す必要はありません。

のテストを書きましょうAccountServiceController:

コントローラ

.controller('AccountServiceController', 
  ['$scope', 'AccountService', 
  function($scope, AccountService) {
    $scope.user = AccountService.getCurrentUser();
  }]
);

テスト

describe('AccountServiceController function', function() {

  describe('AccountServiceController', function() {
    var $scope;

    beforeEach(module('myApp'));

    beforeEach(inject(function($rootScope, $controller) {
      $scope = $rootScope.$new();
      $controller('AccountServiceController', {
        $scope: $scope
        AccountService: {
          getCurrentUser: function () {
            return {
              name: 'Austin Pray',
              id: 1111
            };
          }
        }
      });
    }));

    it('should get the current user', function() {
      expect(typeof $scope.user.name).toBe('string');
    });
  });
});

AccountServiceコストのかかるネットワーク操作を回避し、コントローラはの内部にまったく結合されていません。

于 2014-12-18T06:22:14.163 に答える