backbone.js klicken Sie auf Ereignis-spy ist nicht immer nannte, mit der jasmine.js und sinon.js
Ich versuche zu testen, klicken auf eine Schaltfläche mit backbone.js, jasmine.js und sinon.js. Aber der folgende test case schlägt fehl. Ich bin mit einem Spion zu verfolgen, ob es immer genannt wird oder nicht.
Können Sie mir bitte helfen mit diesem?
Dank.
Neue Aufgabe Vorlage
<script id='new_task_template' type='text/template'>
<input type='text' id='new_task_name' name='new_task_name'></input>
<button type='button' id='add_new_task' name='add_new_task'>Add Task</button>
</script>
NewTaskView
T.views.NewTaskView = Backbone.View.extend({
tagName: 'section',
id: 'new_task_section',
template : _.template ( $("#new_task_template").html() ),
initialize: function(){
_.bindAll( this, 'render', 'addTask');
},
events:{
"click #add_new_task" : "addTask"
},
render: function(){
$(this.el).html( this.template() );
return this;
},
addTask: function(event){
console.log("addTask");
}
});
Jasmin Testfall
describe("NewTaskView", function(){
beforeEach( function(){
this.view = new T.views.NewTaskView();
this.view.render();
});
it("should #add_new_task is clicked, it should trigger the addTask method", function(){
var clickSpy = sinon.spy( this.view, 'addTask');
$("#add_new_task").click();
expect( clickSpy ).toHaveBeenCalled();
});
});
Jasmin Ausgang
NewTaskView
runEvents
runshould #add_new_task is clicked, it should trigger the addTask method
Expected Function to have been called.
- Wo in der DOM hat die Ansicht Rendern selbst? Ist die Vorlage noch innerhalb der specs? Wahrscheinlich Taste#add_new_task existiert nicht in den DOM der Jasmine spec runner und daher
$("#add_new_task").click();
hat keine Wirkung. Wenn Sie sicher sind, dass die view gerendert wird, die mit der richtigen Vorlage, die Sie verwenden konnten NewTaskView element als Kontext für die jquery-Funktion:$('#add_new_task', this.view.el).click();
. - Ich denke, diese Frage ist bereits hier beantwortet: stackoverflow.com/questions/8441612/...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das problem ist das hinzufügen von Ihrem Spion nach Rückgrat hat, bereits gebunden das click-event direkt auf die Funktion addTask (es bedeutet, dass bei der Erstellung der Ansicht). Also dein Spion wird nicht aufgerufen.
Versuchen Sie, die Befestigung der Spion ist ein Prototyp der Ansicht vor Sie es konstruieren. Wie diese:
und dann denken Sie daran, um es zu entfernen:
this.addTaskSpy = sinon.spy(T.views.NewViewTask.prototype, 'addTask');
undT.views.NewViewTask.prototype.addTask.restore()
bedeutet, dass Sie bindend sind, wird das click-Ereignis zu
this.el
- root-element von der Aussicht, welche in Ihrem Fall haben Sie eine IDnew_task_section
. Sie müssen binden Sie es an#add_new_task
was ist deine 'Aufgabe hinzufügen' - Taste, ich gehe davon aus - das sollte es beheben!Update:
$("#add_new_task") finden nicht das element ist, wie die Ansicht nicht Hinzugefügt, um das Dokument im DOM-Baum. verwenden
this.view.$('#add_new_task')
und es sollte funktionieren, da es die Suche für das element in der Abgelöste fragment gespeichert in der Ansicht.el
macht es möglich, die Suche ein wenig zu DOM-das ist nicht angebracht den DOM-Baum noch nicht. #add_new_task ist genau in der Blick - es ist nur die Ansicht nicht in das Dokument - es ist nur im Speicher gehalten und wartet darauf, eingefügt zu werden$(body).append(this.view.el)
nach dem Rendern und du wirst sehen das es dann funktioniert ohne änderung des $('#add_new_task') zuthis.view.$('#add_new_task')
(oder Sie schreiben es$('#add_new_task', this.view.el)
wenn Sie bevorzugen). Es ist 100% richtig Verhaltenjasmine-jquery
Helfer könnte Ihnen helfen, mit Ihren Befestigungen: github.com/velesin/jasmine-jqueryGibt es einige Probleme mit Ihrem Ansatz. Ersten Sie Spion auf Ihre Klasse, die Sie wollen testen, ist nicht der Weg, den ein unit-test sollte funktionieren, führen Sie den test der inneren Logik Ihrer Klasse, und nicht sein Verhalten. Zweitens, und das ist der Grund, warum Ihr test scheitern, werden Sie nicht haben, befestigt Ihr Blick el in die DOM. Also entweder Sie schließen Sie Ihr el auf die DOM -, Feuer-oder das click-Ereignis direkt in die el:
$('#add_new_task', this.view.el).click()
.Btw. backbones Weg zu element erstellen und binden von Ereignissen macht es schwer zu schreiben gute unit-tests führen, dass Sie gezwungen werden, um die Arbeit mit dem DOM und jquery. Eine bessere Art und Weise zu schreiben von testbarem code wäre, immer übergeben alle Abhängigkeiten im Konstruktor und nicht erstellen neuer Instanzen im code verursachen, die schwer zu testen, diese Objekte. Also in deinem Fall wäre es viel einfacher zu injizieren, die el-Objekt im Konstruktor als jquery-Objekt und die Ereignisse manuell. Doing es auf diese Art und Weise können Sie testen Sie die Klasse ohne Abhängigkeiten zu den DOM-oder jquery.
Also in deinem Fall der Konstruktor könnte so Aussehen:
Und Ihr test:
Nachdem Sie alle müssen entscheiden, welches Konzept Ihren Bedürfnissen entsprechen. Schlanker code mit backbones Helfer oder besser testbaren code mit weniger Abhängigkeiten zu jquery, DOM und Rückgrat.