Mocha tests mocking function

19,630

The simplest way to mock a function is to replace the property at runtime.

You can provide your own monitoring function (commonly called a spy), although this is not the most elegant. That would look like:

var called = false;
var testee = new ViewUnderTest();
var originalAttach = testee.attachSelect; // cache a reference to the original
testee.attachSelect = function () {
  called = true;
  var args = [].concat(arguments); // get an array of arguments
  return originalAttach.apply(testee, args);
};

// Perform your test

expect(called).to.be.true;

If you have a test assertion library like chai, you can use the spies plugin and reduce that to:

var testee = new ViewUnderTest();
var spy = chai.spy(testee.attachSelect);
testee.attachSelect = spy;

// Perform your test

expect(spy).to.have.been.called();

Using a spy library will provide some useful features, such as monitoring the number of calls and their arguments to verify low-level behavior. If you're using Chai or Jasmine, I would highly suggest taking advantage of the corresponding support for spies.

Share:
19,630
Wizard
Author by

Wizard

Updated on June 04, 2022

Comments

  • Wizard
    Wizard almost 2 years

    I'm testing backbone view, that have function:

    attachSelect: function(id, route) {
        console.log(id);
        console.log(route);
    
        this.$(id).select2({
            ajax: {
                url: route,
                dataType: 'json',
                results: function(data) {
                    var results = _.map(data, function(item) {
                        return {
                            id: item.id,
                            text: item.title
                        };
                    });
    
                    return {
                        results: results
                    };
                },
                cache: true
            }
        });
    }
    

    I need to rewrite (mock) this fuction that, the looks like:

    attachSelect: function(id, route) {
        console.log(id);
        console.log(route);
    }
    

    How to do that ?