2016-11-16 16 views
3

こんにちは、stackoverflowコミュニティ。メソッドを親コンポーネントに呼び出すコンポーネントの関数をユニットテストする方法

私はAngularプロジェクト(1.5.6)に取り組んでいます。コンポーネントの構造を使って、現在は単体テストを書いています。私はまだユニットテストについて学んでいます。特に、Angularとの関係では、次のような問題について助けを求めることができます。

親コンポーネントからコールバックメソッドを受け取るコンポーネントをテストしようとしています。 。私はメソッドfooを模擬しようとしています(コード例を参照)。残念ながらこのメソッドは親コントローラを呼び出します。

私はそれをテストしようとすると、メソッドが定義されていないと不平を言っています。それから私はspyOnでそれを嘲笑することができると思ったが、私はエラーを得るError: <spyOn> : foobar() method does not exist

私はその方法を模擬することができないと思う。

モジュール:

angular.module("myApp") 
.component("sample", { 
    "templateUrl": "components/sample/sample.html", 
    "controller": "SampleController", 
    "controllerAs": "sampleCtrl", 
    "bindings": { 
     "config": "<", 
     "foobar": "&" 
    } 
}) 
.controller("SampleController", 
      ["$scope", 
    function($scope) { 
     this.isActive = true; 

     this.foo = function() { 
      // do stuff 
      this.isActive = false; 

      // also do 
      this.foobar(); 
     }; 
    } 
); 

ユニットテスト

describe("Component: SampleComponent", function() { 

    beforeEach(module("myApp")); 

    var sampleComponent, scope, $httpBackend; 

    beforeEach(inject(function($componentController, $rootScope, _$httpBackend_) { 
     scope = $rootScope.$new(); 
     sampleComponent = $componentController("sample", { 
      "$scope": scope 
     }); 
     $httpBackend = _$httpBackend_; 
    })); 

    it("should do set isActive to false on 'foo' and call method...", function() { 
     spyOn(sampleComponent, "foobar") 

     expect(sampleComponent.isActive).toBe(true); 
     expect(sampleComponent).toBe(""); 
     expect(sampleComponent.foobar).not.toHaveBeenCalled(); 

     sampleComponent.foo(); 

     expect(sampleComponent.foobar).toHaveBeenCalled(); 
     expect(sampleComponent.foobar.calls.count()).toBe(1); 
     expect(sampleComponent.isActive).toBe(false); 
    }); 
}); 

私はこれにバグを追加しなかった願っていますが、これは上記のは約私がしようとしているものです行う。どんな提案も歓迎されています。もしそのアプローチが間違っているか、より多くの情報が必要なら、教えてください!

+1

'$ componentController'はコンポーネントコントローラをテストするためです。だから、あなたは 'foobar'プロパティにスタブを割り当てなければなりません。 – estus

+0

'foobar'がコントローラのスコープ' this.foobar() 'に割り当てられるので、これがうまくいくと思いました。あなたはスタブをどういう意味ですか?方法? – skofgar

+1

スタブは 'sampleComponent.foobar = jasmine.createSpy()'のように空のスパイです。 $ componentControllerは$ controllerのラッパーです。定義されたコンポーネントコントローラからコントローラを作成し、それ以外のものはすべて無視します。コンポーネントを完全にバインディングでテストするには、 '$ compile'などでコンパイルする必要がありますが、この場合はディレクティブと違いはありません。 – estus

答えて

1

@estusの助けを借りて(問題のコメントを参照)、私はcreateSpyを使ってこの問題を解決できることを知りました。

it("should do set isActive to false on 'foo' and call method...", function() { 
     sampleComponent.foobar = jasmine.createSpy(); 

     expect(sampleComponent.isActive).toBe(true); 
     expect(sampleComponent).toBe(""); 
     expect(sampleComponent.foobar).not.toHaveBeenCalled(); 

     sampleComponent.foo(); 

     expect(sampleComponent.foobar).toHaveBeenCalled(); 
     expect(sampleComponent.foobar.calls.count()).toBe(1); 
     expect(sampleComponent.isActive).toBe(false); 
    }); 

私が使用したいくつかの追加の情報源であった:

関連する問題