2012-11-15 2 views
0

내 백본보기/모델/모음에 대한 통합 테스트를 작성 중입니다. 내가 Viewrender을 호출하면 단순히 템플릿을 자신의 el 속성으로 렌더링하므로 html은 단순히 페이지가 아닌 메모리에 저장됩니다. 내 테스트를 작성하는 재스민을 사용하고백본보기를 테스트 할 때 메모리의 요소에 대한 이벤트 트리거

var model = Backbone.Model.extend({ 
    urlRoot: '/api/model' 
}); 

var view = Backbone.View.extend({ 
    events: { 
     'click #remove': 'remove' 
    } 
    render: function() { 
     var html = _.template(this.template, this.model.toJSON()); 
     this.$el.html(html); 
    }, 
    remove: function() { 
     this.model.destroy(); 
    } 
}); 

: 다음은 간단한 모델 및 DOM 요소에 바인딩 클릭 이벤트와 도면이다. 아래의 테스트에서는 remove 함수의 스파이가 click 이벤트가 뷰에 전달되는 템플릿에있는 #remove 요소에 대해 실행될 때 호출되는지 확인합니다. #remove 요소가 메모리에, 그리고 실제로 DOM에 추가되지 않은 것처럼

// template 

<script id="tmpl"> 
    <input type="button" value="remove" id="remove"/> 
</script> 

// test 

describe('view', function() { 

    var view; 

    beforeEach(function() { 
     view = new view({ 
      template: $('#tmpl').html(), 
      model: new model() 
     }); 
    }); 

    it('should call remove when #remove click event fired', function() {  
     view.$('#remove').click(); 

     var ajax = mostRecentAjaxRequest(); 
     expect(ajax.url).toBe('/api/model'); 
     expect(ajax.method).toBe('DELETE'); 
    }); 

}); 

그러나, 나는 당신이 클릭 이벤트를 시뮬레이션 할 방법을 모르겠어요. 사실 가능한지 확실하지 않습니다.

이상한 조금 시험에서이 작업을 수행 할 수 것처럼 보일 수 있습니다

,하지만 내 테스트와 나는 사이에 무슨 일이 일어나고 있는지 상관 없어 행동 오히려 구현,이 방법 보다 테스트하기 위해 노력하고 - 단지 사용자가 #remove을 클릭하면 DELETE 요청이 서버로 다시 전송되는지 테스트하고 싶습니다.

+0

당신에게 확신이 문제는보기에서'remove' 메서드가 호출되지 않는 것입니다? 나는 메모리에만있는 요소에 대해'click '을 호출하고 예상대로 작동하는 [데모] (http://jsbin.com/ihabom/2/edit)를 만들었습니다. 브라우저 환경이나 phantom.js에서 테스트를 실행하고 있습니까? – dreame4

+0

FWIW, 서버에 대한 요청을 테스트하기 위해 [sinon.js] (http://sinonjs.org/docs/)를 사용하여 조롱하는 것이 좋습니다. 그것은 당신이 설정할 수있는 가짜 서버를 가지고 있습니다. 실제 코드가 유닛 테스트 중에 실제 AJAX 요청을 보내도록하는 것보다 더 빠르며 (더 안전할까요?) –

+0

@DaveNichol 그는 [jasmine-ajax] (https://github.com/pivotal/jasmine-ajax)를 사용하여 아약스 요청을 철저히 분석하는 것처럼 보였으므로 실제 요청이 이루어지지 않았습니다. 이것이'mostRecentAjaxRequest' 호출이 필요한 것입니다. – Gregg

답변

0

click() 버튼을 누르기 전에 render()에 전화하는 것을 잊어 버린 것처럼 보입니다. 모델에 id이 있어야하거나 백본이 실제로 서버에 대한 삭제 호출을 시도하지 않습니다. 이전에 문제가 없었던 것처럼 많은 뷰를 테스트했습니다.

방금 ​​jasmine 2.0 및 jasmine-ajax 2.0에 대해 비슷한 테스트를 수행했습니다.

라이브 코드 :

var MyModel = Backbone.Model.extend({ 
    urlRoot: '/api/model' 
}); 

var MyView = Backbone.View.extend({ 
    events: { 
    'click #remove': 'remove' 
    }, 
    initialize: function(options) { 
    this.template = options.template; 
    }, 
    render: function() { 
    var html = _.template(this.template, this.model.toJSON()); 
    this.$el.html(html); 
    }, 
    remove: function() { 
    this.model.destroy(); 
    } 
}); 

사양 :

describe("testing", function() { 
    var view; 

    beforeEach(function() { 
    jasmine.Ajax.install(); 
    view = new MyView({ 
     template: '<input type="button" value="remove" id="remove"/>', 
     model: new MyModel({id: 123}) 
    }); 
    view.render(); 
    }); 

    it('should call remove when #remove click event fired', function() { 
    view.$('#remove').click(); 

    var ajax = jasmine.Ajax.requests.mostRecent(); 
    expect(ajax.url).toBe('/api/model/123'); 
    expect(ajax.method).toBe('DELETE'); 
    }); 
}); 
관련 문제