2014-01-10 3 views
1

저는 재스민과 마리오네트에 매우 익숙하며 테스트 방법에 대한 도움을 찾고 심지어 내 응용 프로그램 테스트에 대한 올바른 방법을 생각하고 있습니다. 모든 포인터를 환영합니다.Backbone, Marionette, Jasmine : jQuery 지연 이벤트를 테스트하는 방법

모델을 가져와 내보기를 인스턴스화하고 렌더링하는 데 사용하는 마리오네트 컨트롤러가 있습니다. 이 페이지의 맨 아래에있는 메소드를 사용하여 뷰가 렌더링되기 전에 모델을 가져 오도록합니다 : https://github.com/marionettejs/backbone.marionette/blob/master/upgradeGuide.md#marionetteasync-is-no-longer-supported.

내 컨트롤러 방법은 모델을 가져오고보기가 그렇게 보이는 표시 : 모델이 가져온 후 당신이 볼 수 있듯이

showCaseById: function(id){ 
    App.models.Case = new caseModel({ id: id }); 

    var promise = App.models.Case.fetch(); 
    $.when(promise).then(_.bind(this.showContentView, this)); 
}, 

, 그것은 showContentView를 호출합니다. 그 방법은 다음과 같습니다.

showContentView: function(model){ 
    App.views.Body = new bodyView({ 
    model: App.models.Case 
    }); 

    App.views.Body.on('case:update', this.submitCase, this); 

    // this.layout is defined in the controller's initialize function 
    this.layout.content.show(App.views.Body); 
}, 

이 기능을 테스트하는 올바른 방법은 무엇입니까? 약속 완료 후 showContentView 함수 호출을 테스트하고 싶습니다. 이것을 위해 사양을 어떻게해야합니까?

감사합니다. 그리고 그것은 호출 된 주장하여 showContentView 방법에

답변

0

첫째, 스파이 : 둘째

it('showCaseById', function (done) { 
    var controller = new Controller(); 
    spyOn(controller, 'showContentView'); 

    controller.showCaseById('foo'); 
    expect(controller.showContentView).toHaveBeenCalledWith(jasmine.any(caseModel)); 
}); 

, 나는 (당신이 가져 호출을 스텁 추천 할 것입니다) 그래서 당신은 네트워크를 때리지 마세요,하지만 그건 지금 털이 약간지기 시작 : 이제

function caseModel() { 
    this.fetch = function() { 
     // return a promise here that resolves to a known value, e.g. 'blah' 
    }; 
} 

것은, 당신은 약간 강한 주장을 가질 수 있지만, 당신은 당신의 의존성의 내부와 주변 하구 있기 때문에이 조금 shonky입니다 :

expect(controller.showContentView).toHaveBeenCalledWith('blah'); 

caseModel을 재정 의하여 컨트롤러 메서드가 컨트롤러 메서드를 만들 때 이전 버전 대신 새 버전을 가져오고이 테스트 용으로 새 버전의 구현을 제어 할 수 있습니다.

이 코드를 더 테스트 할 수있는 방법이 있지만, 테스트를 시작한 것처럼 보입니다. 나는이 모든 것을 다루지 않을 것입니다. 당신은 더 많은 테스트를 할 때 분명히 스스로를위한 것들을 발견 할 것입니다.

0

우선, _.bind(fn, context)은 실제로 fn을 호출하지 않는다는 것을 이해하는 것이 중요합니다. 대신 호출 될 때 fn()을 호출하는 함수를 반환합니다. context은 fn이 내부적으로 사용하는 객체를 this으로 정의합니다.

그것은 필요는 없습니다하지만 당신은 showCaseById로 작성할 수

내가 말하는대로
showCaseById: function(id){ 
    App.models.Case = new caseModel({ id: id }); 

    var promise = App.models.Case.fetch(); 
    var fn = _.bind(this.showContentView, this); 
    $.when(promise).then(fn); 
}, 

, 즉 불필요하지만 지금은 _.bind() 함수를 반환하는 것을 이해하고 $.when(promise).then(...)는 (첫 번째) 인수로 함수를 사용할 수 있습니다.

실제 질문에 대한 답변을 얻으려면 $.when(promise).then(...) 문을 추가하여 App.models.Case.fetch() 성명을 이행했는지 확인하고 원하는 테스트 기능을 사용하십시오.

showCaseById: function(id){ 
    App.models.Case = new caseModel({ id: id }); 

    var promise = App.models.Case.fetch(); 
    $.when(promise).then(_.bind(this.showContentView, this)); 

    // start: test 
    $.when(promise).then(function() { 
    console.log("caseModel " + id + " is ready");//or alert() if preferred 
    }); 
    // fin: test 
}, 

두 번째 $.when(promise).then(...)은 첫번째와 간섭하지 않습니다. 오히려 둘은 순차적으로 실행됩니다. console.log() satatement는 this.showContentView이 성공적으로 호출되었으며 초기 렌더링이 발생 했어야한다는 신뢰할 수있는 확인을 제공합니다.

이 시점에서 아무 것도 렌더링되지 않으면 나중에 this.showContentView을 디버깅해야한다고 의심해야합니다.

관련 문제