Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spying on a Javascript constructor using Jasmine

I'm writing specs for some Javascript classes (backbone.js views, written in Coffeescript) and I'd like to ensure that one view constructs another.

I'm attempting to do this by spying on the constructor, like so:

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()

The initialize() call on AviaView definitely causes the MatricesView constructor to be called, courtesy this line:

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

It definitely works; if I run the app manually I can see the constructor being called during initialize(). However my Jasmine spec fails:

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.

I've spoken to several of my colleagues, and they agree that this should work ... can anyone suggest a good way of spying on constructors?

like image 726
Duncan Bayne Avatar asked May 01 '26 18:05

Duncan Bayne


1 Answers

How about:

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()
like image 171
Daniel Heath Avatar answered May 03 '26 13:05

Daniel Heath