Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs override a function in a module

Tags:

node.js

I am trying to test a function in a module. This function ( I will refer to it as function_a ) calls a different function ( function_b ) within the same file. So this module looks like this:

//the module file

module.exports.function_a = function (){ 
  //does stuff
  function_b()
};

module.exports.function_b = function_b = function () {
  //more stuff
}

I need to test function_a with a specific result from function_b.

I would like to override function_b from my test file, then call function_a from my test file, resulting in function_a calling this override function instead of function_b.

Just a note, I have tried and succeeded in overriding functions from separate modules, like this question, but that is not what I am interested in.

I have tried the code below, and as far as I know, doesn't work. It does illustrates what I am going for, though.

//test file
that_module = require("that module")
that_module.function_b = function () { ...override ... }
that_module.function_a() //now uses the override function

Is there a correct way to do this?

like image 210
Evan Giesel Avatar asked Sep 03 '14 16:09

Evan Giesel


People also ask

Can I override JavaScript function?

Introduction. It is true that JavaScript supports overriding, not overloading. When you define multiple functions that have the same name, the last one defined will override all the previously defined ones and every time when you invoke a function, the last defined one will get executed.

What is JS override?

Overriding a method replaces the code of the method in the superclass with that of the subclass.


2 Answers

From outside a module's code, you can only modify that module's exports object. You can't "reach into" the module and change the value of function_b within the module code. However, you can (and did, in your final example) change the value of exports.function_b.

If you change function_a to call exports.function_b instead of function_b, your external change to the module will happen as expected.

like image 188
apsillers Avatar answered Oct 13 '22 02:10

apsillers


You can actually use the package rewire. It allows you to get and set whatever was declared in the module

foo.js

const _secretPrefix = 'super secret ';

function secretMessage() {
    return _secretPrefix + _message();
}

function _message() {
    return 'hello';
}

foo.test.js

const rewire = require('rewire');

// Note that the path is relative to `foo.test.js`
const fooRewired = rewire('path_to_foo');

// Outputs 'super secret hello'
fooRewired.secretMessage();

fooRewired.__set__('_message', () => 'ciao')

// Outputs 'super secret ciao'
fooRewired.secretMessage();
like image 28
leoschet Avatar answered Oct 13 '22 01:10

leoschet