2013-10-02 12 views
5

これは重複しているかもしれませんが、私はここで他の多くの質問を見てきました。彼らは通常、私が何らかの形で探しているものを見逃しています。彼らは、彼ら自身が作り出したサービスについて話しています。私がやり遂げることができること。私はどの角度が私のモックで注入されているかを無効にしようとしています。私はそれが同じだろうと思ったが、何らかの理由でコードをステップ実行すると、常に角の$ cookieStoreであり、私のモックではない。ジャスミンを使用してAngularサービスを模擬するにはどうすればよいですか?

私はジャスミンとangularjsでの経験が非常に限られています。私はC#の背景から来た。私は通常単体テストのmoq(C#のフレームをモックする)を書いています。私は私が私のコントローラのいずれかで使用$は、cookiestoreサービスをモックたいこの

[TestClass] 
public PageControllerTests 
{ 
    private Mock<ICookieStore> mockCookieStore; 
    private PageController controller; 

    [TestInitialize] 
    public void SetUp() 
    { 
     mockCookieStore = new Mock<ICookieStore>(); 
     controller = new PageController(mockCookieStore.Object); 
    } 

    [TestMethod] 
    public void GetsCarsFromCookieStore() 
    { 
     // Arrange 
     mockCookieStore.Setup(cs => cs.Get("cars")) 
        .Return(0); 

     // Act 
     controller.SomeMethod(); 

     // Assert 
     mockCookieStore.VerifyAll(); 
    } 
} 

のようなものを見に使用しています。

app.controller('PageController', ['$scope', '$cookieStore', function($scope, $cookieStore) { 

    $scope.cars = $cookieStore.get('cars'); 

    if($scope.cars == 0) { 
      // Do other logic here 
      . 
    } 

    $scope.foo = function() { 
     . 
     . 
    } 
}]); 

私は$ cookieStore.get方法が「ガレージ」引数で呼び出されることを確認します。私はまた、それが戻ってくるものを制御できるようにしたい。私はそれが0を返すようにしたい、そして、私のコントローラは他のロジックをしなければならない。

ここは私のテストです。

describe('Controller: PageController', function() { 

    var controller, 
     scope, 
     cookieStoreSpy; 

    beforeEach(function() { 
     cookieStoreSpy = jasmine.createSpyObj('CookieStore', ['get']); 
     cookieStoreSpy.get.andReturn(function(key) { 
      switch (key) { 
       case 'cars': 
        return 0; 
       case 'bikes': 
        return 1; 
       case 'garage': 
        return { cars: 0, bikes: 1 }; 
      } 
     }); 

     module(function($provide) { 
      $provide.value('$cookieStore', cookieStoreSpy); 
     }); 
     module('App'); 

    }); 

    beforeEach(inject(function(_$httpBackend_, $rootScope, $controller) { 
     scope = $rootScope.$new(); 
     controller = $controller; 
    })); 

    it('Gets car from cookie', function() { 
     controller('PageController', { $scope: scope }); 
     expect(cookieStoreSpy.get).toHaveBeenCalledWith('cars'); 
    }); 
}); 

答えて

5

これは議論の解決策ですw私の前の答えがあった。

私のコントローラでは、私は$ location.pathと$ location.searchを使用しています。だから私のモックで$場所を上書きするには:

locationMock = jasmine.createSpyObj('location', ['path', 'search']); 
locationMock.location = ""; 

locationMock.path.andCallFake(function(path) { 
    console.log("### Using location set"); 
    if (typeof path != "undefined") { 
    console.log("### Setting location: " + path); 
    this.location = path; 
    } 

    return this.location; 
}); 

locationMock.search.andCallFake(function(query) { 
    console.log("### Using location search mock"); 
    if (typeof query != "undefined") { 
    console.log("### Setting search location: " + JSON.stringify(query)); 
    this.location = JSON.stringify(query); 
    } 

    return this.location; 
}); 

module(function($provide) { 
    $provide.value('$location', locationMock); 
}); 

私は$コントローラに何も注入する必要はありませんでした。それはちょうど働いた。ログを見てください:

LOG: '###場所セット使用して'

LOG: '###場所の設定:/テスト'

LOG:「場所の検索を使用して###を{"limit": "50"、 "q": "ani"、 "tags":[1,2]、 "category_id":5} 'を検索します。

+0

+1努力をいただきありがとうございます。場所は私が必要とした次のものです:)それが働いた場合はお知らせください。 – uriDium

0

あなたは、引数をチェックする方法

// declare the cookieStoreMock globally 
var cookieStoreMock; 

beforeEach(function() { 
    cookieStoreMock = {}; 

    cookieStoreMock.get = jasmine.createSpy("cookieStore.get() spy").andCallFake(function(key) { 
    switch (key) { 
     case 'cars': 
     return 0; 
     case 'bikes': 
     return 1; 
     case 'garage': 
     return { 
      cars: 0, 
      bikes: 1 
     }; 
    } 
    }); 

    module(function($provide) { 
    $provide.value('cookieStore', cookieStoreMock); 
    }); 
}); 

上のスパイそして引数はここ

expect(searchServiceMock.search).toHaveBeenCalledWith('cars'); 
+0

私はこれをしていませんか?私のテストを見てください。私はそれをやっていると確信しています。また、私は自分のモックを作成する方法ではなく、私のモックを挿入する方法について尋ねた。 – uriDium

+0

しかし、あなたは$ provide.value( 'cookieStore'、cookieStoreSpy)であるべきですが、$ provide.value( '$ cookieStore'、cookieStoreSpy)を注入しています。 – gnom1gnom

+0

角度サービスであっても?私はドルでそれを参照しなければならないと思った。 – uriDium

0

を行うテストしたい場合、それはモカとCoffeeScriptのコードだ例https://github.com/lucassus/angular-seed/blob/81d820d06e1d00d3bae34b456c0655baa79e51f2/test/unit/controllers/products/index_ctrl_spec.coffee#L3です+ sinon.jsしかし、アイデアは同じです。次のコードで基本的に

は、モジュールをロードし、そのサービスを置き換えることができスニペット:

beforeEach(module("myModule", function($provide) { 
    var stub = xxx; //... create a stub here 
    $provide.value("myService", stub); 
})); 

後で、このスタブサービスを注入し、アサーション行うことができスペックで:

it("does something magical", inject(function(myService) { 
    subject.foo(); 
    expect(myService).toHaveBeenCalledWith("bar"); 
})); 

詳細をあなたがこの優れたブログ記事で見つけた嘲笑とテストに関するヒント:http://www.yearofmoo.com/2013/09/advanced-testing-and-debugging-in-angularjs.html

0

moock cookieを保存する理由moを使わずに直接使用できる場合相違?以下のコードは$ cookieStoreを使用してCookieを取得して取得するコントローラの部分的な単位テストです。あなたのコントローラが$ cookieStore.put( 'cookieName'、cookieValue)を使用する "setACookie"と呼ばれるメソッドを持っている場合、テストは設定された値を読み取ることができます。

describe('My controller', function() { 
    var $cookieStore; 
    describe('MySpecificController', function() { 

    beforeEach(inject(function(_$httpBackend_, $controller, _$cookieStore_) { 
     $cookieStore = _$cookieStore_; 
     // [...] unrelated to cookieStore 
    })); 

    it('should be able to reference cookies now', function() { 
     scope.setACookie(); 
     expect($cookieStore.get('myCookieName')).toBe('setToSomething'); 
    }); 

}); 
関連する問題