期望以函数作为参数来调用函数
我有一组相当简单的主干视图规范:
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 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,我现在真的很尴尬。早上用一双新的眼睛看这个:
...应该是...
测试应该失败,因为我实际上测试了错误的类。
o_O
Right, I'm really embarrassed now. Looking at this with a fresh pair of eyes in the morning:
... should have been ...
The test should have been failing, as I was actually testing the wrong class.
o_O
第一次失败的测试似乎与此问题有关: https://github.com/pivotal/jasmine /issues/45 尝试将你的参数包装在一个数组中:
第二个更令人困惑 -
@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:
The second one is more baffling—there's no way
@matricesView.showError
is undefined (and you could throw in aconsole.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.