繁体   English   中英

TypeError使用Jasmine在CoffeeScript中测试Backbone.js

[英]TypeError testing Backbone.js in CoffeeScript with Jasmine

我目前正在浏览Backbone.js上PeepCode视频,但尝试全部用CoffeeScript而不是裸JavaScript编写。

到目前为止,一切都很好,除非当我尝试对代码运行Jasmine测试时,我遇到了一些TypeErrors:

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

茉莉花测试规范如下:

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时,它工作正常。 奇怪的是,即使Jasmine告诉我TypeError: Cannot call method 'isFirstTrack' of undefined如果我在页面的控制台中运行album.isFirstTrack(0) ,也TypeError: Cannot call method 'isFirstTrack' of undefined但它会返回true因此窗口确实可以访问变量和方法。

原因是范围界定,是的。

当您声明没有var关键字且没有将其附加到另一个对象的album变量时,您将在全局范围内创建一个变量。

这是一个坏主意。 您确实想限制创建的全局对象的数量,因为另一段JavaScript很容易覆盖您的数据或引起冲突等。

从这个角度来看,在测试中调用this.model的想法是正确的。 问题是,你需要连接modelthis是能够做到这一点。 很容易:

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

您所要做的就是说this.album = ... ,您就完成了。 现在您的测试将能够找到this.album并且一切正常。

注意 :我相信Derick的答案是正确的-解释了TypeError: Cannot call method 'isFirstTrack' of undefined消息的TypeError: Cannot call method 'isFirstTrack' of undefined但此答案也可能是相关的。)

你说

当我从方程式中删除jQuery时,它工作正常。

这意味着如果您剪掉jQuery -> ,那么您的测试通过了吗? 如果是这样,那就不是范围问题; 这是一个代码顺序问题。 当您将函数传递给jQuery时,直到文档准备就绪,该函数才会执行。 同时,在定义AlbumAlbumView类之前,您的测试将立即运行。

没有必要使用jQuery ->包装器,因为您的类定义不依赖于任何现有的DOM元素。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM