How can I Mock node-rest-client request? - node.js

I'm using node-rest-client for my project and I've come to the point where I want to start unit testing my classes that utilize node-rest-client. Is there any examples on how I can mock the Client in my tests? I am using Sinon in my unit testing.

Step 1: In the js code you are testing, export the node-rest-client instance so it can be available to your test code. For example in myApp.js, I put this:
var Client = require('node-rest-client').Client;
var restClient = new Client();
exports.restClient = restClient; //instance now available outside this module
restClient.get(someUrl, ...); //actual node rest client call
Step 2: In your test code, create a wrapper function that returns a fake function, and use sinon to mock it into your target code. This allows you to inject the return data and response code during your test setup.
var nodeRestGet = function (data, statusCode) {
return function (url, cb) {
cb(data, { statusCode: statusCode || 200 });
}
};
sinon.stub(myApp.restClient, 'get').callsFake(nodeRestGet("", 200));
Step 3: Write your test code. Note that you might want to restore the method (remove the mock) if you are running multiple tests:
myApp.doThings(); // TEST
myApp.restClient.get.restore(); // removes the mock

Related

How to persist() when using nockNack with jest and Node?

I am currently working on some unit tests for an express app.
I am using "jest": "^29.4.1", "nock": "^13.3.0",.
The tests I am writing use nockBack.
Imagine I have 3 separate test files that run the code below. The first 2 properly run, save a nock fixture in the proper directory and then re-run just fine. As soon as I introduce a 3rd test; it runs and passes the first time (and saves a fixture etc...) but if I re-run the 3rd test it fails with this error error: Error [NetworkingError]: Nock: No match for request.... I read in the docs that a way to alleviate this is to use the persist() method BUT this is not documented for nockBack only for methods using nock to make calls to pseudo endpoints. I am testing 3rd party api calls that need to go out initially on the netowrk and then subsequent calls will be pulled from the fixtures.
I tried clearing interceptor use by adding these to all my tests:
beforeEach(() => nock.cleanAll());
afterEach(() => nock.cleanAll());
But this does not help to make the 3rd test pass when re-running.
I also tried adding persist() like so: const { nockDone } = await nockBack('post-data.json').persist(); <---- but this fails since it's not a recognized method.
Is there a way to make this work when using nockBack?
Test 1
const nockBack = require('nock').back;
const path = require('path');
const { getPosts } = require('./post');
nockBack.fixtures = path.join(__dirname, '__nock-fixtures__');
nockBack.setMode('record');
test('return a list of posts by a user', async () => {
const userId = 1;
const { nockDone } = await nockBack('post-data.json');
const data = await getPosts(userId);
expect(data.length).toBeGreaterThan(0);
data.forEach((post) => {
expect(post).toEqual(
expect.objectContaining({
userId,
})
);
});
nockDone();
});

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.

Is there any real time example to write unit test cases for azure nodejs function using mocha or jest tool

Is there any real time example to write unit test cases for azure nodejs function using mocha or jest tool
Testing an Azure Function is no different than testing any Javascript module exporting an async function.
One tricky part is passing a mocked context to the function under test. For this, you can use stub-azure-function-context.
For a complete quickstart, you may want to check my blog post Unit testing Azure Functions with Jest and TypeScript
It's a good habit to extract the main functionality from a function in an own class/module/function. Because AWS Lambda, Azure Functions and GCP Function have a small changes in the interface and this will make migration much easier.
For example:
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
// You can call and await an async method here
return {
body: "Hello, world!"
};
}
Would be:
// keep just a single line of code here
module.exports = async function (context, req) {
return doAction();
}
const doAction = () => {
context.log('JavaScript HTTP trigger function processed a request.');
// You can call and await an async method here
return {
body: "Hello, world!"
};
}
And now you can a Jest test on doAction(), with plain Node, without coupling with Lambda/Functions code

Jest with fetch-mock generating error: TypeError: Cannot read property 'prototype' of undefined when using on nodejs

I'm almost sure it's my mistake, but I spent one entire day trying to solve and I've being failed 😞.
I'm trying to configure the fetch-mock on node to use with jest. I tried a lot of things and the best result that I have is this:
https://user-images.githubusercontent.com/824198/50566568-7b49e400-0d22-11e9-884f-89720899de3a.png
I'm sure my mock is working because if I pass it through parameter to the "Myclass.query" it works perfectly.
I'm also sure that the mock is arriving in my test file, because the mock function is present in the fetch module.
But... all together aren't working 😭.
I created a very simple and small project to see this problem happening:
https://github.com/cesarjr/test-node-fetch
Can anyone help me?
Jest uses the mock at __mocks__/node-fetch.js any time node-fetch is required during the test.
The problem is that the first thing fetch-mock does is require node-fetch.
This means that Request is not defined when it is set on the config here, so calling prototype on the undefined Request causes an error here.
Someone smarter than me might know how to force Jest to require the actual node-fetch when fetch-mock requires node-fetch in the mock for node-fetch, but from what I can see it doesn't look like it is possible.
Looks like you will have to delete the mock at __mocks__/node-fetch.js and pass fetch to your code, something like this:
myclass.js
class MyClass {
static query(fetch, sessionId, query) {
const url = 'https://api.foobar.com';
const body = {
sessionId,
query
};
return fetch(url, {
method: 'post',
body: JSON.stringify(body)
})
.then(res => res.json());
}
}
module.exports = MyClass;
...then create the sandbox in your test and pass it to your code, something like this:
myclass.test.js
const fetch = require('fetch-mock').sandbox();
const MyClass = require('./myclass');
describe('MyClass', () => {
describe('.query', () => {
it('returns the response', () => {
fetch.mock('*', {'result': {'fulfillment': {'speech': 'The answer'}}});
expect.assertions(1);
return MyClass.query(fetch, '123', 'the question').then((data) => {
expect(data.result.fulfillment.speech).toBe('The answer'); // SUCCESS
});
});
});
});
I've now found a reliable way to combine fetch-mock and jest http://www.wheresrhys.co.uk/fetch-mock/#usageusage-with-jest

Jasmine spyOn function argument object, as Variables are not defined

I am wiring jasmine test cases for one of the application. I have just started learning jasmine.
Below is my script code
var aclChecker = function(app,config) {
validateResourceAccess = function (req, res, next) {
req.callanotherMethod();
res.send(401,'this is aerror message');
}
}
Now i want to spyOn res and req object to know if send method has been called.
As req and res are not global variables i am having this doubt on how to create a spy on in junit spec
Please help!!!!!!!!
You can simply mock req and res like this.
describe("acl checker", function() {
it("should validate resource access", function() {
var mockReq = {
callAnotherMethod: function() {}
};
var mockRes = {
send: function() {}
};
var mockNext = {};
spyOn(mockReq, "callAnotherMethod");
spyOn(mockRes, "send");
aclChecker.validateResourceAccess(mockReq, mockRes, mockNext);
expect(req.callAnotherMethod).toHaveBeenCalled();
expect(res.send).toHaveBeenCalledWith(401, 'this is aerror message');
});
});
Typically, in a unit test you would mock any resource requests and only validate that the request is proper. So you would instead call a mock request library, and validate that the url and headers are correct.
However, if you really want to test the actual access to the resource, you will need to build your request object first, and give yourself access to it afterwards.
If you want to learn about request mocking, check out jasmine-ajax:
https://github.com/pivotal/jasmine-ajax
If you still want to do this, you should use a beforeEach function in the test file to create the dependencies you need for your tests.
Take a look at this for more help with beforeEach:
https://github.com/pivotal/jasmine/wiki/Before-and-After

Resources