2017-05-17 20 views
0

sinon 스파이로 백본 모델의 이벤트가 발생했음을 테스트 할 때 콘솔 로그가 메서드 본문에 삽입 될 때 실행되는 것처럼 보이지만 오류 : expected doSomething to be called once but was called 0 times이 잘못 표시됩니다. 나는 그 당신이 new Model() 호출하기 전에 라인에 const spy = sinon.spy(Model.prototype, 'doSomething'); 같은 모델의 프로토 타입에 sinon 스파이를 넣어야 할 것, 해결하기 위해 알고Karma와 Sinon을 사용할 때 이벤트 버스에 바인딩 된 백본 모델의 메서드가 실행되었음을 테스트 할 수 있습니까?

it('Y U NO WORK', function() { 
    const events = {}; 
    _.extend(events, Backbone.Events); 
    const Model = Backbone.Model.extend({ 
     initialize: function() { 
      this.listenTo(events, 'doSomething', this.doSomething); 
     }, 
     doSomething: function() {}, 
    }); 
    const model = new Model(); 
    const spy = sinon.spy(model, 'doSomething'); 
    events.trigger('doSomething'); 
    sinon.assert.calledOnce(spy); 
}); 

그러나이 문제시하지 않고 작동하는 것 같다 : 같은 테스트 기능은 보인다 아래와 같이 모델 인스턴스에 넣어 :

it('And this does work', function() { 
    const Model = Backbone.Model.extend(); 
    const model = new Model(); 
    const spy = sinon.spy(model, 'set'); 
    model.set('foo', 'bar'); 
    sinon.assert.calledOnce(spy); 
}); 

호기심이 첫 번째 인스턴스에서 모델의 프로토 타입에 넣어해야하지만 두 번째의 모델 인스턴스에서 작동하는 이유는 무엇입니까?

답변

1

스파이 류는 원본 메소드를 호출 할 때 알 수있는 맞춤 메소드로 대체합니다 (나중에 복원하기 위해 원본을 유지함). 따라서 첫 번째 경우에는 스파이를 만들기 전에 이벤트 리스너를 설정합니다. 이벤트 시스템은 실제로 스파이가 아닌 원래 방법을 직접 참조하고 있습니다. 스파이는 그것에 대해 아무 것도 할 수 없으며 스파이는 언제 호출되는지 알 수 없습니다.

it('Y U NO WORK', function() { 
    var spy; 
    const events = {}; 
    _.extend(events, Backbone.Events); 
    const Model = Backbone.Model.extend({ 
     initialize: function() { 
      spy = sinon.spy(this, 'doSomething'); 
      this.listenTo(events, 'doSomething', this.doSomething); 
      //now same as this.listenTo(events, 'doSomething', spy); 
     }, 
     doSomething: function() {}, 
    }); 
    const model = new Model(); 
    events.trigger('doSomething'); 
    sinon.assert.calledOnce(spy); 
}); 

또는 같은 원래의 방법으로 직접 참조를 유지하지 않도록 :

this.listenTo(events, 'doSomething', function() { 
    //by the time this is invoked, original has been replaced with spy 
    this.doSomething(); 
}); 

그것은 좋겠

당신은 이벤트 리스너, 뭔가를 설정하기 전에 먼저 스파이를 설정해야 원래의 메소드에 대한 참조를 보유하고 있지 않기 때문에 작동합니다. 메소드 호출은 동적입니다.