TypeError тестирует Backbone.js в CoffeeScript с помощью Jasmine - PullRequest
0 голосов
/ 22 сентября 2011

В настоящее время я работаю с видео PeepCode на Backbone.js , но пытаюсь написать все это на CoffeeScript, а не на чистом JavaScript.

Пока все хорошо, кроме случаев, когда я пытаюсьчтобы запустить тесты Jasmine в коде, который я запускаю при некоторых ошибках типа:

TypeError: Cannot call method 'isFirstTrack' of undefined
TypeError: Cannot call method 'get' of undefined

Мой файл CoffeeScript / Backbone выглядит следующим образом:

jQuery ->
  class window.Album extends Backbone.Model
    isFirstTrack: (index) ->
    index is 0

  class window.AlbumView extends Backbone.View
    tagName:    'li'
    className:  'album'

    initialize: ->
      @model.bind('change', @render)
      @template = _.template $('#album-template').html()     
    render: =>
      renderedContent = @template @model.toJSON()
      $(@el).html(renderedContent)
      return this

И спецификация теста Jasmine выглядит так:*

var albumData = [{
  "title":  "Album A",
  "artist": "Artist A",
  "tracks": [
    {
        "title": "Track A",
        "url": "/music/Album A Track A.mp3"
    },
    {
        "title": "Track B",
        "url": "/music/Album A Track B.mp3"
    }]
}, {
  "title": "Album B",
  "artist": "Artist B",
  "tracks": [
    {
        "title": "Track A",
        "url": "/music/Album B Track A.mp3"
    },
    {
        "title": "Track B",
        "url": "/music/Album B Track B.mp3"
  }]
}];

describe("Album", function () {

  beforeEach(function () {
    album = new Album(albumData[0]);
  });

  it("creates from data", function () {
    expect(this.album.get('tracks').length).toEqual(2);
  });

  describe("first track", function() {
    it("identifies correct first track", function() {
      expect(this.album.isFirstTrack(0)).toBeTruthy();
    })
  });

});

Я предполагаю, что проблема связана с CoffeeScript, заключающим в себе все функции.Когда я удаляю jQuery из уравнения, он работает нормально.Странно, хотя, хотя Жасмин говорит мне TypeError: Cannot call method 'isFirstTrack' of undefined, если я запускаю album.isFirstTrack(0) в консоли на странице, она возвращает true, поэтому у окна действительно есть доступ к переменным и методам.

Ответы [ 2 ]

2 голосов
/ 22 сентября 2011

( Примечание : я считаю, что ответ Дерика правильный - он объясняет сообщение TypeError: Cannot call method 'isFirstTrack' of undefined - но этот ответ также может быть уместным.)

Вы говорите

Когда я удаляю jQuery из уравнения, он работает нормально.

Это означает, что если вы вырежете строку jQuery ->, тогда ваши тесты пройдут?Если это так, то это не проблема области;это проблема порядка кода.Когда вы передаете функцию в jQuery, эта функция не выполняется, пока документ не будет готов.Между тем, ваши тесты запускаются немедленно - до того, как будут определены классы Album и AlbumView.

Нет смысла использовать оболочку jQuery ->, поскольку определения ваших классов не зависят от существующих DOM.элементы.

2 голосов
/ 22 сентября 2011

причина в том, что да,

когда вы объявляете переменную album без ключевого слова var и не присоединяете ее к другому объекту, вы создаете переменную в глобальной области действия.

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

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

  beforeEach(function () {
    this.album = new Album(albumData[0]);
  });

все, что вам нужно сделать, это сказать this.album = ... и все готово. теперь ваши тесты смогут найти this.album и все должно работать.

...