Is there any way to mock a variable inside a function? - node.js

The code works like this
let getToken = await apiCall();
apiCall() calls a few internal functions and populates getToken variable with a token. The problem is, in my tests, I can't seem to populate that variable with anything. It is always undefined and an error gets thrown. Is there any way to populate this variable with a dummy value in a unit test?
EDIT
constructor() {
this._token = '';
}
I want to inject a value in token via a unit test. I'm trying to use sinon right now.

Related

How to mock a 'request' node module for testing in jest

I am new to writing test cases in jest and i wanted to test 'mark' function and want to mock 'request' node module. let's say this file's name is app.js and test file will be app.test.js
Can someone tell how to write its test case?
const request = require("request")
var test = {
mark: function(data,cb){
data.url = "localhost"
request(data, function(err,response,body){
if(!response){
err.response = false
}
cb(err,body)
})
}
}
module.exports = test;
If I understand your question correctly, you are asking two questions:
How to write the test and mock the request
What test cases you should write
Regarding the mock, I recommend using nock which is an npm module for mocking network requests.
To the second question, I believe that you should map the logic in the function and create the test cases from there. Think about the function, look at every if else/calculation/loop and it’s possible outcomes and create test cases from there.
The mark function doesn’t have a lot of logic, it’s send a request, updates the err variable according to the response and calling the callback.
The only outcome we can test to to see that if the request works, the cb is called correctly without modifications. And if the request returns empty, change the err var and call the callback.
To do so we need to mock the request and return a response to match the test case and validate that the cb was called correctly (can be done with a mock).
Test case example:
The test case may be a bit abstract since I don’t have the real use case of the function but it shows the point
it("Should mark response false when it does not exist", () => {
const DATA = {} // your data object
const callback = jest.fn();
nock('localhost')
.get('/example')
.reply(500) // Exaple of mocking the resonse. Custom it to be more specific depending on mark.
test.mark(DATA, callback);
// Verify that the function was called.
expect(callback).toHaveBeenCalled();
// Verify that `err.response` was false.
expect(callback.mock.calls[0][0].response).toBe(false)
})
You can read more about mocking and verifying parameters here.

Sinon stub function used with destructuring

I wish to stub a function used in the file I'm currently testing. This function is required with a destructuring like this:
const { theFunctionIWant } = require('path/to/module')
When testing, the stub is never called, and the real function proceed to be called.
But when I require it 'normally' (i.e: without destructuring)
const myModule = require('path/to/module')
then the stub is correctly used and everything works fine
I sense that it's because of how the destructuring works and the fact that sinon stub the object property and not the function directly. Anyhow if you can provide me some insights I will be grateful !
The reason stubbing the method of the module doesn't work when using destructuring from a dependant module is quite simple and has to do with the time you bind the actual function reference. It doesn't have anything to do with CommonJS modules, Sinon or Node per se, so I'll start out with simple javascript examples.
const stub = (o, method) => (o[method] = () => "I am a stub");
const obj = {
methodFoo() {
return "I am foo";
}
};
// same as doing `const methodFoo = obj.methodFoo;`
const { methodFoo } = obj; // "import" using destructuring
console.log("obj.methodFoo(): ", obj.methodFoo());
console.log("methodFoo()", methodFoo());
console.log("Stubbing out method!");
stub(obj, "methodFoo");
console.log("obj.methodFoo: ", obj.methodFoo());
console.log("methodFoo()", methodFoo());
If you run the example above, you will see that even though
you have stubbed the methodFoo property of the obj "module",
the directly bound reference still returns the old value!
This is because, when stubbing you are essentially assigning
a new value (a function) to a property of an object (here: obj). New references to this new value (using obj.methodFoo) will print the new values,
but if you have stored a reference to the old function you will
still get the old return values when calling the old function.
The same applies to your original problem. If you in module A have a dependency
on a function foo in module B and store that reference, then
it doesn't matter if you assign a new value (for instance a stub) to
the exported value, since you already stored a reference to the old value.
In essence:
This will be affected by stubbing
const A = require('./A');
function doFoo(){
A.foo(); // will always evalute A['foo']()
}
This will not be affected by stubbing
const myFoo = require('./A').foo;
function doFoo(){
myFoo(); // will just evalute to the original value of A.foo()
}
Since your module returns an object and theMethodIwant is property of that object you can define your stub like this:
const myModule = require('path/to/module')
myModule.theMethodIwant = sinon.stub()

Can I fetch a local variable's value from a mocked function?

I have a function say MyFunction(arg) which I have mocked.
Inside the function, another function is called and the result of the second function is assigned to a local variable(say myVar) declared inside MyFunction(arg).
Can I use mockito anyway to fetch the value of myVar in my test function?
Adding code :
OrderOperations.java
public OrderResponse createOrder(Orders order){
OrderResponse orderResponse = new OrderResponse();
ManipulatedOrder = partnerOrder;
partnerOrder = parseXML(order) //This function manipulates the details of order object and gives back the result.
String xmlRequest = xs.toXML(partnerOrder); //The response is converted to XML
//Few modifications are done to the xmlRequest and then it is sent to another function
orderResponse = invokeAPI(xmlRequest); //This function uses the xmlRequest.
return orderResponse;
}
I want to test this function using JUNIT, mock this function and in someway want to capture what is being sent to invokeAPI if I pass test values to the Orders object.

How to test the content of callback of method

I might not be getting something but I am trying to test the callback content of a method but without calling the method.
The function I am trying to test
functionToSkip(param1, param2, function(arg1, arg2){
if(arg1){
// Do some things here
} else {
// Do other things here
}
}
What I am trying to do is to test the content of the callback function with differents args values that I can change in the tests and the parameter of the functionToSkip can be anything.
All I successfully did is to skip the call of the function but I cannot call the callback method.
I did stub the function to skip and even trying to give values to the callback method but there is not any logs showing.
var spy = sinon.stub(Class, "functionToSkip").calledWith(param1, param2, ("arg1","arg2"))
The main method that is calling the stubbed function works since I can see the logs prior of the function when I call it in the tests.
First of all, if functionToSkip is an instance method on Class, it will be a property on Class.prototype, not Class itself. In order to stub, you can do one of two things:
Create an instance, and create the stub:
instance = new Class(/*costructor arguments*/)
var stub = sinon.stub(instance, 'functionToSkip')
Or, stub on the prototype:
var stub = sinon.stub(Class.prototype, 'functionToSkip');
In the second case, since class prototypes are global state, I'd recommend restoring it-- preferably in something like mocha afterEach to ensure it gets cleaned up whether your test is successful or not. This way it doesn't screw with other tests in your run:
stub.restore()
Between the two, though, I recommend the first approach.
Next up... If you want to make assertions on the content of calls, the firs thing you'll probably want to do is assert that it was in fact called with the signature you're looking for:
sinon.assert.calledWith(stub, sinon.match.any, sinon.match.any, sinon.match.func)
The any matcher allows any value, and the func matcher requires a func. After that, you can obtain the callback function like so:
var cb = stub.firstCall.args[2]
And invoke it like so:
cb('arg1', 'arg2');
As to what assertions you'd do after invoking the callback function-- I'd have to know more about what you're trying to test about it to make recommendations.

what should nodeJS/commonJS module.exports return

I know that I can set module.exports to either an object or a function
(and in some cases a function that will return an object).
I am also aware of the differences and ways to use exports vs. module.exports so no need to comment on that.
I also understand that whatever is returned is cached and will be returned on any consecutive call to require. So that if I choose to return a function and not an object then possibly this implies that on every require It is necessary to actually run this function.
I was wondering is there any defacto standard on which of those two should be used. Or if there is no such standard - what considerations would apply when deciding if my module should return an object, a function or anything more complicated...
The module I intend to write is expected to be used as part of an express application if it matters (maybe there is a "local defacto standard" for express/connect modules).
If the require'd code is standalone, and does not need access to any objects from the parent code, I export an object.
edit - the above is my preferred way to do it. I do the below only when I need to pass stuff into the module, like configuration data, or my database object. I haven't found a more elegant way to give the module access to variables that are in the parents' scope.
So to pass an object from parent into module I use a function:
//parent.js
var config = { DBname:'bar' };
var child = require('./child.js')(config);
//child.js
module.exports = function(cfg){
var innerchild = {};
innerchild.blah = function(){
console.log(cfg.DBname); // this is out of scope unless you pass it in
}
return innerchild;
};
"so that if I choose to return a function and not an object then
possibly this implies that on every require It is necessary to
actually run this function."
It does not matter whether you return an individual function or an object. In neither cases a function (or functions) are ran. unless you explicitly do so.
For instance, consider the a module hello.js:
exports = function () { return 'Hello'; };
You can use require to get that function:
var hello = require('hello');
If you want to run that function, you need to invoke it explicitly as follows:
var hello = require('hello')();
You wrote you want to make sure your function is executed exactly once. Intuitively this could lead you to writing your hello.js as follows:
var hello = function () { return 'Hello'; };
exports = hello();
In which case you could just store result from hello via require:
var hello = require('hello');
However: if you do that the export system may cache your module. In such cases, you do not get fresh result from hello, but instead, a cached value. This may or may not be what you want. If you want to make sure a function is invoked every time it is required, you need to export a function and call it after require.

Resources