Getting a ReferenceError when unit testing with Mocha

vicentelee
Participant II

I'm trying to unit test with Mocha but I'm kind of stuck.

I've seen this post https://community.apigee.com/articles/3964/unit-testing-javascript-code-with-mocha-sinon-and.html but can't get my tests to run without breaking my Api proxy.

I'd like to test this file: myapi/src/gateway/myapi/apiproxy/resources/jsc/util/myUtil.js

myutil.js serves a util for jsc/mypolicy.js it just does some data manipulation.

Now, in order for me to use mocha, I need to expose myUtil.js by adding

modules.exports = myUtil;

However, as soon as I do that, the Api proxy tracer spits out this error:

ReferenceError: "module" is not defined

So my question is, how am I able to reference myUtil from a mocha test file, like so:

myUtil = require(path/to/myUtil);
resp = myUtil.manipulate(oldResponse);
expect(resp.nextPage).to.equal("example.com"); 
Solved Solved
0 9 2,810
1 ACCEPTED SOLUTION

Hi @Vicente Lee

You can use the rewire module for that. Here is an example:

Assume your myUtils.js is something like this:

// myUtils.js

function add(a, b) {
  return a + b;
}

You can write the following test using rewire:

var expect = require('expect.js');
var rewire = require('rewire');

var app = rewire('./myUtil.js');

describe('feature: add', function() {
  it('should add two numbers', function() {
    var add = app.__get__('add');
    expect(add(1,1)).to.equal(2);
  });
});

View solution in original post

9 REPLIES 9

Hi @Vicente Lee

You can use the rewire module for that. Here is an example:

Assume your myUtils.js is something like this:

// myUtils.js

function add(a, b) {
  return a + b;
}

You can write the following test using rewire:

var expect = require('expect.js');
var rewire = require('rewire');

var app = rewire('./myUtil.js');

describe('feature: add', function() {
  it('should add two numbers', function() {
    var add = app.__get__('add');
    expect(add(1,1)).to.equal(2);
  });
});

Thank you that worked. Maybe this might be a new question but under these constraints, is there a way to stub out context.getVariable("blah");

So for instance:

// myUtils.js

function add(a,b) {
return context.getVariable("blah") + a + b;
}

I can always change the function to take in three params to get around the context.getVariable() function, but can that function be stubbed out? I tried a few variations with rewire but none seem to work. I always end up with

context.getVariable is not a function

And that can be solved with something like (keeping the function names same for continuity):

// myUtils.js

function add(a, b) {
  var c = context.getVariable('c');
  return (a + b) * c;
}
// test.js

var expect = require('expect.js');
var sinon = require('sinon');
var rewire = require('rewire');

var app = rewire('./myUtil.js');

var fakeContext = {
  getVariable: function(s) {}
}

var contextGetVariableMethod;

beforeEach(function () {
  contextGetVariableMethod = sinon.stub(fakeContext, 'getVariable');
});

afterEach(function() {
  contextGetVariableMethod.restore();
});

describe('feature: add', function() {
  it('should add two numbers', function() {
    contextGetVariableMethod.withArgs('c').returns(3);
    app.__set__('context', fakeContext);

    var add = app.__get__('add');
    expect(add(1,1)).to.equal(6);
  });
});

Thanks so much for the detailed answer!

On second thought, I tried this line by line, but it's not stubbing out context.getVariable for some reason. I get a typeError stating context.getVariable is not a function. Basically, I'm trying to stub out context.getVariable("Response.content");

When I run the test with ./node_modules/.bin/mocha test.js, it is passing. I think that proves that stubbing is working fine.

Have you tried to copy/paste ^ that code and see if it passes for you?

Thanks it works now, what was throwing me off is the to.equal part. Apparently the version I'm using does not recognize to.equal. Also I make the mistake of not putting the context.getVariable within a function.

Hi @ozanseymen ,

    I don't have any function inside myutil.js. basically what it does is taking the data from request and doing some validations on that data

 

var address = context.getVariable('request.address1'); 
if (Boolean(address)) { 
   address = address.trim().toUpperCase(); 
}

 

so i have written the test code like below

 

var myutil = rewire('../resources/jsc/util.js')
var fakecontext = {
    getVariable: function(s) {}
  }
  
  var contextGetVariableMethod;
  beforeEach(function () {
    contextGetVariableMethod = sinon.stub(fakecontext, 'getVariable');
  });
  
  afterEach(function() {
    contextGetVariableMethod.restore();
  });

describe('testing req res address',function(){
    it('testcase for compare address',function(done){
        myutil.__set__(context,fakecontext)
    contextGetVariableMethod.withArgs('request.address1').returns(' abcd ');
    
});
});

 

but when i run this code , i am always getting  

 

context.getvariable() is not a function

 

any suggestions to solve this?

Please do not ask new questions on threads that are 4 years old.