Can't get chai.spy.on to work

℡╲_俬逩灬. 提交于 2021-02-08 05:36:17

问题


Please don't suggest to use Sinon. I want to get chai-spies specifically chai.spy.on working with your help. Basically, I have this spec. Inside my initialize method in PatientController, I call this.initializePatientEvents();

beforeEach(function() {
  this.patientController = new PatientController({model: new Backbone.Model(PatientModel)});
});

it('executes this.initializePatientEvents', function () {
  let spy = chai.spy.on(this.patientController, 'initializePatientEvents');
  expect(spy).to.have.been.called();
});

However, the test is failing with this error

AssertionError: expected { Spy } to have been called
at Context.<anonymous>

I spent almost 3 hours now with no luck! :(


回答1:


Moving my comment above to a response here:

Looking at your code, I'm just not sure what the this reference refers to. And based on your error message, it seems like its related to something about the context. Therefore, I'd try something like this:

var patientController;

beforeEach(function() {
    patientController = new PatientController({model: new Backbone.Model(PatientModel)});
});

it('executes this.initializePatientEvents', function () {
    let spy = chai.spy.on(patientController, 'initializePatientEvents');
    expect(spy).to.have.been.called();
});

If this doesn't work, then its more specific to your implementation of patientController and the initializePatientEvents method, and not something related to chai.spy.

EDIT: Here's something I set up locally and I was able to get a passing test. The main difference is that instead of using Backbone, I just created my own constructor function.

"use strict";
var chai = require("chai");
var sinon = require("sinon");
var sinonChai = require("sinon-chai");
chai.use(sinonChai);
var expect = chai.expect;
var should = chai.should();

describe("PatientController Test", function() {
    var PatientController;
    var initializePatientEventsSpy;
    var patient;

    beforeEach(function() {
        PatientController = function(name, age) {
            this.name = name;
            this.age = age;
            this.initializePatientEvents();
        };

        PatientController.prototype.initializePatientEvents = function() {
            console.log("Do some initialization stuff here");
        };

        initializePatientEventsSpy = sinon.spy(PatientController.prototype, "initializePatientEvents");
    });

    it("should test initializePatientEvents was called", function() {
        patient = new PatientController("Willson", 30);
        initializePatientEventsSpy.should.have.been.called;
    });
});



回答2:


If the PatientController constructor is what calls initializePatientEvents, then the timing of your spy creation is a bit off. Currently, the order of your spy-function relationship is:

  1. Call function
  2. Spy on function
  3. Expect spied on function to have ben called

Because the function is not being spied on when it is called, the spy misses the call entirely. What the order should be is:

  1. Spy on function
  2. Call function
  3. Expect spied on function to have ben called

However, you are in the sticky situation where the object you are spying on doesn't exist until after the constructor is called. One workaround would be to assert that the effects of the initializePatientEvents have taken place instead of asserting that the function was called.



来源:https://stackoverflow.com/questions/33849605/cant-get-chai-spy-on-to-work

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!