тестирование backbone.js просмотра событий с помощью jasmine - PullRequest
8 голосов
/ 29 сентября 2011

Я пытаюсь реализовать тесты представления для реализации Coffeescript в вездесущем примере 'todo' backbone.js (см. Github.com/rsim/backbone_coffeescript_demo.)

Мои тесты с жасмином из вышеприведенной демонстрации работают довольно хорошо, за исключением событий просмотра. Я ожидаю, что застрял в одном или обоих из следующих пунктов: i) Я не понимаю привязку события в коде представления, ii) Я не понимаю, как правильно настроить тест Жасмина для событий кода представления.

Вот пример события 'edit' ...

class TodoApp.TodoView extends Backbone.View
  tagName: "li"
  template: TodoApp.template '#item-template'
  events:
    "dblclick div.todo-content" : "edit"
     ...

  initialize: ->
    _.bindAll this, 'render', 'close'
    @model.bind 'change', @render
    @model.bind 'destroy', => @remove()

  render: ->
    $(@el).html @template @model.toJSON()
    @setContent()
    this

  edit: ->
    $(@el).addClass "editing"
    @input.focus()
  ...

... теперь вот проверка того, был ли достигнут фокус при двойном щелчке:

    describe "edit state", ->
      li = null

    beforeEach ->
       setFixtures('<ul id="todo-list"></ul>')
       model = new Backbone.Model id: 1, content: todoValue, done: false
       view = new TodoApp.TodoView model: model, template: readFixtures("_item_template.html")
       $("ul#todo-list").append(view.render().el)
           li = $('ul#todo-list li:first')
       target = li.find('div.todo-content')
       expect(target).toExist()
               target.trigger('dblclick') # here's the event!

    it "input takes focus", ->
       expect(li.find('.todo-input').is(':focus')).toBe(true)

Ожидание ни i) шпиона, ни ii) фокуса не выполнено.

Есть ли какая-то особенность в тестировании кода события backbone.js, о которой я должен знать в Jasmine?

Ответы [ 4 ]

2 голосов
/ 21 сентября 2012

Я не очень хорош в coffescript, поэтому я могу что-то упустить, но где вы настраиваете своего шпиона?

Чтобы протестировать вызов событий, вам может потребоваться обновить события представления, как только вы установитеШпион.

spyOn(view, 'edit');
view.delegateEvents();
target.trigger('dblclick');

it("should call edit when target is double clicked", function() {
  expect(view.edit).toHaveBeenCalled()
});
2 голосов
/ 29 сентября 2011

вы шпионите за методом edit представления. это заменяет метод шпионским объектом, что означает, что фактический метод редактирования не будет вызван. следовательно, вы @input.focus никогда не будете стрелять.

, поскольку вы хотите, чтобы тест фактически вызывал ваш метод редактирования, я бы удалил шпиона для него.

примечание: не вызывайте expect методов в вашем beforeEach. если вам действительно нужно установить ожидание для них, создайте для них блок it.

0 голосов
/ 23 июня 2015

Проблема в том, что объект Backbone.View events использует делегирование события .Чтобы события можно было назвать работающими, элемент должен быть частью DOM, вы можете сделать это, выполнив что-то вроде $('body').append(someView.el) в вашем beforeEach.Лично я стараюсь не проверять, правильно ли Backbone устанавливает events и запускает ли щелчки вручную, для модульных тестов более практично вызывать обработчики обратного вызова, полностью избегая DOM, что может сильно замедлить ваши тесты.

Для :focus та же проблема, в DOM должен быть элемент, чтобы jQuery мог определить, сфокусирован ли элемент.В этом случае лучше установить какое-либо состояние как часть вашего компонента, а не проверять состояние с помощью запроса DOM, например: someView.hasFocus === true.В качестве альтернативы вы можете следить за реализацией элементов focus и проверять, была ли она вызвана.

0 голосов
/ 19 февраля 2013

Я не писал свой тест в coffeescript, но у меня была такая же проблема, поэтому я надеюсь, что вы простите меня за ответы в javadcript. В итоге я разбил ваш тест на два разных теста. Во-первых, я проверил, установил ли фокус на поле ввода вызов функции редактирования представления. После этого я проверил, вызывается ли редактирование, когда дважды щелкнул ярлык, и еще не прошел этот тест. Но вот как я проверял, работала ли функция редактирования.

 describe ("A todo item view", function(){
    var my_model;
    var todo_view;

    beforeEach(function(){
       my_model = new Todo({content:"todo value", done:false});
       todo_view = new TodoView({model:my_model});

    });


   it("should set the focus on the input box when the edit function is called", function(){ 
        $('body').append( todo_view.$el ); //append the view to Specrunner.html
        todo_view.edit(); //call the view's edit function
        var focus= document.activeElement;  //finds what element on the page has focus
        expect(focus).toBe('.todo-input');  //jasmine-jquery matcher checks if focused element has the .todo-input class
});

Что может вызывать проблемы, так это то, что ваша модель и ваше представление объявлены внутри beforeEach. Объявление их внутри beforeEach означает, что они существуют только внутри области видимости beforeEach и больше не существуют, когда вы запускаете его.

Кроме того, setFixtures делает то, что вы думаете, что он делает? Фокус не может быть установлен на элемент, который не является частью дерева DOM, поэтому я добавил el вида в тело самой спецификации жасмина. (Я использую html specrunner, а не версию командной строки) Это делает его частью дерева dom и, следовательно, позволяет ему иметь фокус, а также делает его тестируемым.

...