2011-11-29 40 views
3

我正在编写一些JavaScript类(backbone.js视图,用Coffeescript编写)的规范,我想确保一个视图构造另一个视图。使用Jasmine监听Javascript构造函数

我试图通过刺探构造函数来做到这一点,像这样:

describe 'Avia.AviaView', -> 

    beforeEach -> 
    @aviaView = new Avia.AviaView() 
    @matricesView = new Backbone.View() 
    spyOn(Avia.MatricesView, 'constructor').andReturn @matricesView 

    describe 'initialize', -> 

    beforeEach -> 
     @aviaView.initialize() 

    it 'creates a new MatricesView ', -> 
     expect(Avia.MatricesView.constructor).toHaveBeenCalledOnce() 

initialize()通话AviaView肯定会导致MatricesView构造函数被调用,礼貌这一行:

new Avia.MatricesView($("#tabs-3")).initialize() 

它绝对有效;如果我手动运行应用程序,我可以看到在initialize()期间被调用的构造函数。但是我的茉莉花规格失败:

Running Jasmine specs... 
F 

Avia.AviaView initialize creates a new MatricesView . (/Users/dev/avia/spec/javascripts/views/avia_view_spec.js.coffee:13) 
    Expected constructor to be called exactly once, but was called '0' times (line ~14) 
    expect(Avia.MatricesView.constructor).toHaveBeenCalledOnce(); 

FAIL: 1 test, 1 failure, 0.008 secs. 

跟我谈过的几个同事,他们一致认为这应该工作 ...谁能建议刺探构造的一个好办法吗?

+0

从乍一看,这似乎是它与范围有关。第二个beforeEach函数如何访问[at] aviaView的第一个实例?尝试改变beforeEach - > beforeEach =>,这样它会保持父范围。也可以尝试在aviaView之前定义[at] aviaView视图。 CoffeeScript不像Ruby那样[at]自动使它成为一个实例变量。所以不让我输入符号。 – Sandro

+0

谢谢 - 我试图将所有内容都移动到同一个范围内,但问题仍然存在。我很确定问题在于我在做构造函数的时候“做错了”......但是我不知道什么是正确的方式_is_。 –

回答

5

如何:

describe 'Avia.AviaView', -> 

    beforeEach -> 
    @aviaView = new Avia.AviaView() 
    @matricesView = new Backbone.View() 
    spyOn(Avia, 'MatricesView').andReturn @matricesView 

    describe 'initialize', -> 

    beforeEach -> 
     @aviaView.initialize() 

    it 'creates a new MatricesView ', -> 
     expect(Avia.MatricesView).toHaveBeenCalledOnce() 
+0

如果我在监视一个内置对象(如Date),该怎么办? 'spyOn(日期, '构造')andCallThrough(); var d = new Date(); expect(Date.constructor).toHaveBeenCalled();' – jab

+0

如果JS运行时不允许你修改核心对象/类,你需要创建一个包装对象并在你正在测试的类中使用它。这是静态语言中的一种常见技术(其中模拟/存根较难)。 –