web-dev-qa-db-ja.com

Jasmine単体テストでのAngularJSモジュールの依存関係のモック

他のモジュールを依存関係とするモジュール内のコントローラーコードを単体テストしようとしていますが、それらを適切にモックする方法を理解できていません。

Jasmine Frameworkを使用し、Karma(Testacular)でテストを実行しています。

モジュールコード

var app = angular.module('events', ['af.widgets', 'angular-table']);

app.controller('eventsCtrl', function([dependencies]){
    $scope.events = [];
    ...
});

仕様コード

describe('events module', function(){
    var $scope,
        ctrl;

    beforeEach(function(){
        angular.mock.module('af.widgets', []);
        angular.mock.module('angular-table', []);
        module('events', ['af.widgets', 'angular-table']);
    });

    beforeEach(inject(function($rootScope, $controller){
        $scope = $rootScope.new();
        ctrl = $controller('NameCtrl', {
            $scope: $scope,
        });
    }));

    it('should have an empty events array', function(){
        expect($scope.events).toBe([]);
    })
});

私が得ているエラーはKarmaが "no module af.widgets"であるため、明らかにモジュールの依存関係をあざ笑っていません。ヒントはありますか?

71
fscof

1つ以上のサービスを宣言するモジュールをモックする場合は、このコードを使用しました。

beforeEach(function(){
    module('moduleToMock');
    module(function ($provide) {
        $provide.value('yourService', serviceMock);
    });
});

これは、モックするサービスがユニットテスト(別のジャスミン記述)でもあるサービスである場合に役立ちます。 fscofが提案するソリューションは問題ありませんが、angular-tableモジュールの単体テストを作成することはできません。

65
Davide Icardi

ここに私が理解したものがあります:

Karma.conf.jsファイルに「角度テーブル」モジュールをロードしていなかったため、エラーが発生しました。これは、実際のテーブルモジュールなしで「イベント」モジュールをテストしたかったため、最初は意図的なものでした。

テストフォルダーに「mocks/angular-table.js」という名前の新しいファイルを作成して、「angular-table」モジュールを簡単にモックでき、次のコードを追加しました。

/ mocks/angular-table.js

'use-strict';
angular.module('angular-table', []);

このファイルをkarma.conf.jsファイルに、テストしたい実際の「イベント」モジュールとともに追加しました。

karma.conf.js

...
files = [
    JASMINE,
    JASMINE_ADAPTER,
    'scripts/libs/angular.js',
    'scripts/libs/angular-mocks.js',
    'scripts/events.js', // this is the real module.
    'scripts/mocks/*.js', //loads all custom mocks.
    'scripts/specs/*.spec.js' // loads my spec file.
] 
...

最後に、仕様ファイルで、beforeEachブロックで個別に呼び出すことで、両方のモジュールを追加できました。

specs/events.spec.js

beforeEach(function(){
    module('angular-table');
    module('events');
});

this post からこの方法でファイルを構成するというアイデアを得ました

46
fscof

私は最近、AngularJSでのモックテストを簡単にするngImprovedTestingをリリースしました。

あなたの場合、ジャスミンテストで次を使用してください:

beforeEach(ModuleBuilder.forModule('events').serviceWithMocks('eventsCtrl').build());

NgImprovedTestingの詳細については、紹介ブログ投稿をご覧ください: http://blog.jdriven.com/2014/07/ng-improved-testing-mock-testing-for-angularjs-made-easy/ =

3
Emil van Galen