1. ホーム
  2. angularjs

[解決済み] Jasmineを使ってAngularJSのサービスをテストするにはどうすればよいですか?

2022-11-16 10:43:01

質問

(関連する質問はこちらです。 Jasmineのテストでは、AngularJSモジュールが表示されません。 )

Angularをブートストラップせずにサービスをテストしたいだけなのです。

私はいくつかの例とチュートリアルを見ましたが、私はどこにも行きません。

3つだけファイルがあります。

  • myService.js:AngularJSのサービスを定義します。

  • test_myService.js: サービスに対するJasmineのテストを定義します。

  • specRunner.html: 通常のjasmineの設定を含むHTMLファイルです。 で、前の2つの他のファイルとJasmine、Angularjs、angular-mocks.jsをインポートしています。

これはサービスのコードです(私がテストしていないときは期待通りに動作します)。

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

myModule.factory('myService', function(){

    var serviceImplementation   = {};
    serviceImplementation.one   = 1;
    serviceImplementation.two   = 2;
    serviceImplementation.three = 3;

    return serviceImplementation

});

私はサービスを分離してテストしようとしているので、私はそれにアクセスし、それらのメソッドをチェックすることができるはずです。 私の質問は、AngularJSをブートストラップせずにテストにサービスを注入するにはどうすればよいですか?

例えば、どのように私はこのようにJasmineでサービスのメソッドのために返される値をテストすることができます。

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){
            myModule = angular.module('myModule');
                    //something is missing here..
            expect( myService.one ).toEqual(1);
        })

    })

});

どのように解決するのですか?

問題は、サービスをインスタンス化するファクトリーメソッドが、上記の例では呼び出されていないことです(モジュールを作成するだけでは、サービスのインスタンス化は行われません)。

サービスをインスタンス化するために angular.injector は、サービスが定義されているモジュールで呼び出されなければなりません。それから、サービスのために新しいインジェクタオブジェクトを要求することができ、サービスが最終的にインスタンス化されるのはその時だけです。

このように動作します。

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){
            var $injector = angular.injector([ 'myModule' ]);
            var myService = $injector.get( 'myService' );
            expect( myService.one ).toEqual(1);
        })

    })

});

もう一つの方法は、サービスを関数に渡すことで、' 呼び出し ':

describe('myService test', function(){
    describe('when I call myService.one', function(){
        it('returns 1', function(){

            myTestFunction = function(aService){
                expect( aService.one ).toEqual(1);
            }

            //we only need the following line if the name of the 
            //parameter in myTestFunction is not 'myService' or if
            //the code is going to be minify.
            myTestFunction.$inject = [ 'myService' ];

            var myInjector = angular.injector([ 'myModule' ]);
            myInjector.invoke( myTestFunction );
        })

    })

});

そして最後に、「正しい」方法として、' インジェクト ' と ' モジュール ' の中に、' の前に というjasmineのブロックに注入します。 その際、'inject'関数がangularjsの標準パッケージではなく、ngMockモジュールに含まれていること、そしてjasmineでのみ動作することを認識する必要があります。

describe('myService test', function(){
    describe('when I call myService.one', function(){
        beforeEach(module('myModule'));
        it('returns 1', inject(function(myService){ //parameter name = service name

            expect( myService.one ).toEqual(1);

        }))

    })

});