期望以函数作为参数来调用函数

发布于 2024-12-19 23:07:18 字数 2217 浏览 3 评论 0原文

我有一组相当简单的主干视图规范:

describe 'Avia.MatricesView', ->

  beforeEach ->
    @model = {
      bind: ->
      fetch: ->
    }
    spyOn(Avia, 'Matrices').andReturn(@model)
    @matricesView = new Avia.AviaView(addFixtureDiv('fixture'))

  describe 'initialization', ->

    beforeEach ->
      spyOn(@model, 'bind')
      spyOn(@model, 'fetch')
      @matricesView.initialize()

    it 'creates a new Matrices model', ->
      expect(Avia.Matrices).toHaveBeenCalledOnce()

    it 'binds the model change event to render', ->
      expect(@model.bind).toHaveBeenCalledWith('change', @matricesView.render)

    it 'fetches the model data', ->
      expect(@model.fetch).toHaveBeenCalledWith(success: @matricesView.render, error: @matricesView.showError)

MatricesView 的作用正如规范所期望的那样:

initialize: =>
  @model = new Avia.Matrices()
  @model.bind('change', @render)
  @model.fetch(success: @render, error: @showError)

showError: =>
  alert('An error occurred while fetching data from the server.')

render: =>
  html = JST['views/matrices_view_template']()
  @el.html(html)

创建新 Matrices 模型的期望通过了。不过,其他两个规范失败了,其方式让我感到困惑:

Avia.MatricesView initialization binds the model change event to render. (/home/duncan/avia/spec/javascripts/views/matrices_view_spec.js.coffee:21)
  Expected spy bind to have been called with [ 'change', Function ] but was called with [ [ 'change', Function ] ] (line ~22)
    expect(this.model.bind).toHaveBeenCalledWith('change', this.matricesView.render);

Avia.MatricesView initialization fetches the model data. (/home/duncan/avia/spec/javascripts/views/matrices_view_spec.js.coffee:24)
  Expected spy fetch to have been called with [ { success : Function, error : undefined } ] but was called with [ [ { success : Function, error : Function } ] ] (line ~25)
    expect(this.model.fetch).toHaveBeenCalledWith({

据我所知,Jasmine 认为规范范围内 @matricesView.render 返回的函数与该函数不同由 MatricesView 实例范围内的 @render 返回。

另外,我完全不明白为什么在 MatricesView 中明确定义了 @matricesView.showError 时它却未定义。

任何帮助将不胜感激。我确实需要第二双眼睛来关注这个,因为我现在有点疲倦了:-/

I have a fairly straightforward set of specs for a backbone view:

describe 'Avia.MatricesView', ->

  beforeEach ->
    @model = {
      bind: ->
      fetch: ->
    }
    spyOn(Avia, 'Matrices').andReturn(@model)
    @matricesView = new Avia.AviaView(addFixtureDiv('fixture'))

  describe 'initialization', ->

    beforeEach ->
      spyOn(@model, 'bind')
      spyOn(@model, 'fetch')
      @matricesView.initialize()

    it 'creates a new Matrices model', ->
      expect(Avia.Matrices).toHaveBeenCalledOnce()

    it 'binds the model change event to render', ->
      expect(@model.bind).toHaveBeenCalledWith('change', @matricesView.render)

    it 'fetches the model data', ->
      expect(@model.fetch).toHaveBeenCalledWith(success: @matricesView.render, error: @matricesView.showError)

The MatricesView does just as the spec expects:

initialize: =>
  @model = new Avia.Matrices()
  @model.bind('change', @render)
  @model.fetch(success: @render, error: @showError)

showError: =>
  alert('An error occurred while fetching data from the server.')

render: =>
  html = JST['views/matrices_view_template']()
  @el.html(html)

The expectation that a new Matrices model is being created passes. The other two specs fail, though, in ways that confuse me:

Avia.MatricesView initialization binds the model change event to render. (/home/duncan/avia/spec/javascripts/views/matrices_view_spec.js.coffee:21)
  Expected spy bind to have been called with [ 'change', Function ] but was called with [ [ 'change', Function ] ] (line ~22)
    expect(this.model.bind).toHaveBeenCalledWith('change', this.matricesView.render);

Avia.MatricesView initialization fetches the model data. (/home/duncan/avia/spec/javascripts/views/matrices_view_spec.js.coffee:24)
  Expected spy fetch to have been called with [ { success : Function, error : undefined } ] but was called with [ [ { success : Function, error : Function } ] ] (line ~25)
    expect(this.model.fetch).toHaveBeenCalledWith({

As far as I can tell, Jasmine thinks that the function returned by @matricesView.render in the scope of the spec is different to the function returned by @render in the scope of the instance of the MatricesView.

Also, I completely fail to understand why @matricesView.showError is undefined when it's clearly defined in MatricesView.

Any help would be greatly appreciated. I definitely need a second pair of eyes on this as mine are a bit weary right now :-/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

许仙没带伞 2024-12-26 23:07:18

是的,我现在真的很尴尬。早上用一双新的眼睛看这个:

@matricesView = new Avia.AviaView(addFixtureDiv('fixture')) 

...应该是...

@matricesView = new Avia.MatricesView(addFixtureDiv('fixture')) 

测试应该失败,因为我实际上测试了错误的类。

o_O

Right, I'm really embarrassed now. Looking at this with a fresh pair of eyes in the morning:

@matricesView = new Avia.AviaView(addFixtureDiv('fixture')) 

... should have been ...

@matricesView = new Avia.MatricesView(addFixtureDiv('fixture')) 

The test should have been failing, as I was actually testing the wrong class.

o_O

风情万种。 2024-12-26 23:07:18

第一次失败的测试似乎与此问题有关: https://github.com/pivotal/jasmine /issues/45 尝试将你的参数包装在一个数组中:

expect(@model.bind).toHaveBeenCalledWith(['change', @matricesView.render])

第二个更令人困惑 - @matricesView.showError 不可能是未定义的(你可以抛出一个console.log 来确认这一点)。所以这可能只是一个字符串化问题;尝试生成一个简化的测试用例并发布到 Jasmine 问题跟踪器。但就让测试通过而言,请尝试数组包装。如果这不起作用,是否 Jasmine 正在测试引用相等性而不是深度对象相等性?如果是这种情况,您可能想尝试最近添加的 objectContaining 匹配器。

The first failed test seems to be related to this issue: https://github.com/pivotal/jasmine/issues/45 Try wrapping your arguments in an array:

expect(@model.bind).toHaveBeenCalledWith(['change', @matricesView.render])

The second one is more baffling—there's no way @matricesView.showError is undefined (and you could throw in a console.log to confirm this). So that's probably just a stringification problem; try producing a simplified test case and posting to the Jasmine issue tracker. But as far as getting the test to pass, try the array wrapping. If that doesn't work, could it be that Jasmine is testing for reference equality rather than deep object equality? If that's the case, you might want to try the recently-added objectContaining matcher.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文