roman
roman

Reputation: 97

How to spy on a property that is not exported

I have a module "sitescollection" like this:

var site = require('./site');    // <- this should be stubbed

var sitesCollection = function(spec) {

  var that = {};

  that.sites = {};

  that.findOrCreateById = function(id) {
    if (typeof(that.sites[id]) == "undefined") {
      that.sites[id] = site({id: id});            // <- its used here
    }
    return that.sites[id];
  };

  return that;
};

module.exports = sitesCollection;

so within sitescollection, site is a module that is not exported. But inside the code, i use it. Now i'm writing jasmine specs for #findOrCreateById().

I want to spec my the findOrCreateBy() function. But i want to stub the site() function, because the spec should be independent from the implementation. Where do i have to create the spyed method on?

var sitescollection = require('../../lib/sitescollection');

describe("#findOrCreateById", function() {
  it("should return the site", function() {
    var sites = sitescollection();
    mysite = { id: "bla" };
    // Here i want to stub the site() method inside the sitescollection module.
    // spyOn(???,"site").andRetur(mysite);
    expect(sites.findOrCreateById(mysite.id)).toEqual(mysite);
  });
});

Upvotes: 4

Views: 793

Answers (1)

Jamie Mason
Jamie Mason

Reputation: 4196

You can achieve this using https: //github.com/thlorenz/proxyquire

var proxyquire = require('proxyquire');

describe("#findOrCreateById", function() {
    it("should return the site", function() {

        // the path '../../lib/sitescollection' is relative to this test file
        var sitesCollection = proxyquire('../../lib/sitescollection', {
            // the path './site' is relative to sitescollection, it basically
            // should be an exact match for the path passed to require in the
            // file you want to test
            './site': function() {
                console.log('fake version of "./site" is called');
            }
        });

        // now call your sitesCollection, which is using your fake './site'
        var sites = sitesCollection();
        var mysite = {
            id: "bla"
        };

        expect(sites.findOrCreateById(mysite.id)).toEqual(mysite);
    });
});

Upvotes: 1

Related Questions