2

そこで、私が書いたAngularJSアプリケーションの単体テストを書き始めました。このアプリケーションはログインページで保護されているため、ユーザー名がログインしていない場合、ログインページ以外のページへのリクエストはログインページをリダイレクトします。このロジックは、アプリケーションの起動時に1回だけ実行する必要があるため、メインモジュールの.run()メソッドから実行されますが、メインモジュールの.run()メソッド内から実行されるコードをテストする方法はありますか?私は次のテストコードを持っています:

describe('Login Controller', function(){
    'use strict';

    var scope, controller, $httpBackend, $resource, callback;

    beforeEach(module('application'));

    beforeEach(inject(function($injector, $rootScope, $controller, $http, $location, authentication, session) {
        $httpBackend = $injector.get('$httpBackend');
        $httpBackend.expectGET('/api/v1/authentication').respond({status: 'success', data: null});
        $resource = $injector.get('$resource');
        callback = jasmine.createSpy();
        scope = $rootScope.$new();
        controller = new $controller('Login', {
            $scope: scope,
            $http: $http,
            $location: $location,
            authentication: authentication,
            session: session
        });
    }));

    afterEach(function() {
        $httpBackend.verifyrifyNoOutstandingExpectation();
        $httpBackend.verifyNoOutstandingRequest();
    });

    it('should verify all default values for controller', function() {
        expect(scope.username).toEqual('');
        expect(scope.password).toEqual('');
        expect(scope.displayApplicationLoad).toEqual(false);
        expect(angular.isFunction(scope.login)).toEqual(true);
        expect(angular.isFunction(scope.logout)).toEqual(true);
        expect(scope.loggedIn).toEqual(false);
        expect(scope.headerTemplate).toEqual('/templates/core/header.html');
        expect(scope.footerTemplate).toEqual('/templates/core/footer.html');
    });
});

問題は、メインモジュールの.run()メソッド内で実行されているコードが考慮されていないことです。

$httpBackend.expectGET('/api/v1/authentication').respond({status: 'success', data: null});

ライン。このコードを単体テストできるように、このロジックを別の場所に配置する必要がありますか?

4

2 に答える 2

6

テストするすべてのコードをサービスに移動し、実行ブロックに挿入します。次に、このサービスを個別にテストできます。また、認証に依存する他のものをより柔軟にテストするためのモジュールを設定できます。

于 2012-11-06T06:46:18.003 に答える
0

モジュールの run メソッドをテストする方法を見つけたと思います。少しハックですが、仕事は完了です。これが私の解決策です:

describe( 'my module', function() {

  var runBlocks;

  beforeEach( function() {
     var myModule = angular.module( 'modules.flow' );

     runBlocks = myModule._runBlocks;
     myModule._runBlocks = [];

     module( 'myModule' );
  } );

  afterEach( function() {
     angular.module( 'modules.flow' )._runBlocks = runBlocks;
  } );

  describe( 'when loaded', function() {

     beforeEach( inject( function( $injector ) {

        // Here you could e.g. configure $httpBackend

        for( var i = 0; i < runBlocks.length; ++i ) {
           $injector.invoke( runBlocks[i] );
        }
     } ) );

     // Tests ...

  } );

} );

まず、モジュールに定義されたすべての実行ブロックのコピーを作成し、実行ブロックの内部リストを削除します。次に、実行ブロックが成功するために必要なセットアップを行い、その後、インジェクターに関数を呼び出させることができます。

ただし、実行ブロック内のコードを適切なサービスに抽出する機会がある場合は、その方法を優先する必要があります。

更新:不足しているafterEachメソッドを追加

更新 2:への呼び出しを修正angular.module

于 2013-03-18T11:19:39.243 に答える