Try catch unit test (jest) in javascript - javascript

I have following script employeeJobTransferServiceLive.js:
const createJobTrasferSetPayloadOutput = async (jobTransferSetPayload) => {
const file = './output/jobTransferSetPayload.json';
try {
await fs.writeFile(file, JSON.stringify(jobTransferSetPayload, null, 4), { overwrite: false });
return JSON.stringify(jobTransferSetPayload);
} catch (err) {
return err;
}
};
so I created following unit test employeeJobTransferServiceLive.test.js:
const empJobTransferSrvc = require('../../../libs/employeeJobTransferSet/employeeJobTransferServiceLive');
jest.mock('fs', () => ({
promises: {
writeFile: jest.fn(),
},
}));
describe('sendWFDRequest is called', () => {
afterEach(() => {
jest.resetModules();
jest.clearAllMocks();
});
it('Create and Write to the file', async () => {
const result = await empJobTransferSrvc.createJobTrasferSetPayloadOutput(jobTransferSetPayload);
expect(JSON.parse(result)[0]).toEqual(jobTransferSetPayload[0]);
expect(result).not.toBeNull();
});
});
The problem the compiler complain about test coverage for line return err; after catch.
I don't know how to create unit test to cover it.

Maybe it is not best answer, but at least it works fine for me
const fs = require('fs').promises;
const empJobTransferSrvc = require('../../../libs/employeeJobTransferSet/employeeJobTransferServiceLive');
jest.mock('fs', () => ({
promises: {
writeFile: jest.fn(),
},
}));
describe('sendWFDRequest is called', () => {
afterEach(() => {
jest.resetModules();
jest.clearAllMocks();
});
it('Create and Write to the file', async () => {
const result = await empJobTransferSrvc.createJobTrasferSetPayloadOutput(jobTransferSetPayload);
expect(JSON.parse(result)[0]).toEqual(jobTransferSetPayload[0]);
expect(result).not.toBeNull();
});
it('should handle a writeFile error', async () => {
jest.spyOn(fs, 'writeFile').mockRejectedValue(new Error('something went wrong'));
try {
await empJobTransferSrvc.createJobTrasferSetPayloadOutput(jobTransferSetPayload, logger);
} catch (error) {
expect(error.message).toEqual('Error: something went wrong');
}
});
});

Related

jest fn mock isnt working if not assigned in it and assigned in for each

i am trying to write tests using jest
the integration is a call that have a private function called test- gets called by funcTest
trying to mock implementation in before each how ever the mock does not work and it goes to the real function "test".
when i put the assignment (integration['test']=mockFn;) inside the "it" it works perfectly .
example for working code:
describe('test', () => {
const mockFn: jest.Mock = jest.fn();
beforeEach(async () => {
const integration = new integrationTest();
})
afterEach(() => {
jest.restoreAllMocks();
});
it('call mock implemntaion', async () => {
integration['test']=mockFn;
mockFn.mockImplementation(() => {
throw new Error('error');
});
try {
await integration.funcTest();
} catch (e) {
expect(e).toBeInstanceOf(Error);
}
});
})
example of not working code:
describe('test', () => {
const mockFn: jest.Mock = jest.fn();
beforeEach(async () => {
const integration = new integrationTest();
integration['test']=mockFn;
})
afterEach(() => {
jest.restoreAllMocks();
});
it('call mock implemntaion', async () => {
mockFn.mockImplementation(() => {
throw new Error('error');
});
try {
await integration.funcTest();
} catch (e) {
expect(e).toBeInstanceOf(Error);
}
});
})
why does this happen
and how to fix
thanks

How to mock optimizelySDK.createInstance().onReady() using Jest?

Here is my mock file __mocks__/#optimizely/optimizely-sdk.js
const optimizelySDK = jest.requireActual('#optimizely/optimizely-sdk')
optimizelySDK.createInstance().onReady = () => ({ success: false }))
module.exports = optimizelySDK
Here is my test file Optimizely.test.js
import optimizelySDK from '#optimizely/optimizely-sdk'
test('onReady', () => {
const response = optimizelySDK.createInstance().onReady()
expect(response).toBe({ success: false })
})
I think I might be going about this all wrong. This worked perfectly when I try this with lodash. I believe this is because optimizelySDK is a class. I think I should be mocking that instead. How do I successfully mock and test optimizelySDK?
For anyone who came across this on Google, I had the same problem and got it working with jest:
jest.mock('#optimizely/optimizely-sdk', () => ({
...jest.requireActual('#optimizely/optimizely-sdk'),
createInstance: () => ({
getEnabledFeatures: jest.fn().mockReturnValueOnce(['featureA', 'featureB']),
onReady: jest.fn().mockResolvedValueOnce({ status: 200 })
})
}))
describe('my-test', () => {
it('should pass', async () => {
const result = await getFeatures()
console.log(result) // ['featureA', 'featureB']
// assert on result here
});
});
where my code looked something like:
const getFeatures = async (event) => {
try {
const optimizelyInstance = optimizelySDK.createInstance({
sdkKey: process.env.OPTIMIZLEY_SDK_KEY,
});
const optimizelyParameters = {}
return optimizelyInstance.onReady().then(() => {
const result = optimizelyInstance.getEnabledFeatures('id', optimizelyParameters);
return result;
});
} catch (err) {
console.error('Could not get features', err);
}
};

Hide console logs in JEST test

I'm new to JEST and testing in general and having trouble figuring out the following.
I have the following script that is part of a CLI tool.
I would like to stop the spinner outputs when testing.
I have tried spyOn/mock, but to no avail.
const ora = require('ora');
const spinner = new ora();
const chalk = require('chalk');
const fs = require('fs');
module.exports = path =>
new Promise((resolve, reject) => {
spinner.text = chalk.blue('Creating directory...');
spinner.start();
fs.mkdir(path, err => {
if (!err) {
spinner.succeed(chalk.bgGreen('Directory created\n'));
resolve(true);
} else {
spinner.fail(chalk.bgRed(`Directory already exists: ${path}`));
reject(err);
}
});
});
this is my test:
const createDir = require('./utils/createDir');
const fs = require('fs');
describe('createDir function', () => {
const folders = {
base: './.test',
fail: './.test/fail',
success: './.test/success'
};
beforeAll(() => {
fs.mkdirSync(folders.fail, { recursive: true });
});
afterAll(() => {
fs.rmdirSync(folders.base, { recursive: true });
});
it('creates the directory', async () => {
await expect(createDir(folders.success)).resolves.toBe(true);
});
it('fails if directory exists', async () => {
await expect(createDir(folders.fail)).rejects.toThrow();
});
});
You should be able to just add
jest.mock('ora')
in the beginning of your test. It will auto-mock the entire library replacing each of the methods with jest.fn() (without any implementation) so the calls from the implementation will have no effect on the output.
EDIT by Ben:
The functional mock turned out to be this:
jest.mock('ora', () => {
return jest.fn().mockImplementation(() => {
return {
start: () => {},
fail: () => {},
succeed: () => {}
};
});
});

How to test in JEST a request that downloads a file

I want to unit test the exported method in the code below. Trying to write unit tests for a function that is downloading a zip file from a localhost server.I will write my function bellow so you understand better:
export const downloadCdn = async (cdnUrl, out) => {
const download = (resolve, reject) => {
const req = request({
method: 'GET',
uri: cdnUrl
});
req.on('response', (data) => {
// do something
});
req.on('error', (data) => {
// do something
});
req.on('data', (chunk) => {
// do something
});
req.on('end', () => {
console.log('download done');
});
req.pipe(out);
out.on('close', () => {
resolve([null, 'done']);
});
};
const downloadSummary = new Promise(download);
return downloadSummary
.then(() => [null, 'Done'])
.catch(err => [err, null]);
};
Here are my test file, what I'm trying to achieve is to have unit test that validates the download of the zip file:
import request from 'request';
import * as Module from './downloadCdn';
jest.mock('request', () => {
const mockRequest = {
pipe: jest.fn(),
on: jest.fn(),
};
return function () {
return mockRequest;
};
});
describe('Downloading a file', () => {
it('Should find the module', () => {
expect(typeof Module.downloadCdn === 'function').toBeTruthy();
});
it('Should download the zip', async () => {
const [error, response] = await Module.downloadCdn(cdnUrl, out);
expect(response === 'Done').toBeTruthy();
expect(error === null).toBeTruthy();
});
});
The response from the Promise, I receive inside the test is null, no error catching. Here is the error received from jest:
expect(received).toBeTruthy()
Expected value to be truthy, instead received false
While mocking the request, you should resolve the promise. I think that promise is not resolving that's why it's not working. I hope that the below code will be fixed your problem.
jest.mock('request', () => {
const mockRequest = {
pipe: jest.fn(),
on: (parameter, callback) => {
callback();
},
};
return function () {
return mockRequest;
};
});

How to test superagent promise

I have a function that I use for HTTP requests:
export default {
getRequest: (url, params) => {
return new Promise((resolve, reject) => {
superagent.get(url)
.query(params)
.set('Accept', 'application/json')
.end((err, response) => {
if (!response) {
reject(new Error('Something went wrong...'));
return;
}
const payload = response.body || response.text;
if (err) {
reject(payload || err);
return;
}
resolve(payload);
});
});
}
};
I want to test this function when Promise resolves or rejects.
My test looks like this:
import superagent from 'superagent';
import HTTPAsync from '../HTTPAsync';
describe('HTTPAsync. test', () => {
describe('getRequest test', () => {
const url = '/url';
const params = { param: 'value' };
const result = HTTPAsync.getRequest(url, params);
it('Should be promise', () => {
expect(result).toBeInstanceOf(Promise);
});
it('Should be pfromise', () => {
expect(result.resolve()).toBe('');
});
});
});
But I dont know how to resolve returned promise in happy scenario or error and check results of function
I made another type of test, and that helped me:
import superagent from 'superagent';
import HTTPAsync from '../HTTPAsync';
describe('HTTPAsync. test', () => {
describe('getRequest test', () => {
superagent.get = jest.fn(url => {
return superagent;
});
superagent.query = jest.fn(query => {
return superagent;
});
superagent.set = jest.fn(args => {
return superagent;
});
superagent.end = jest.fn(cb => cb(null, { text: 'zaebis voda' }));
const url = 'localhost:5000/url';
const params = { param: 'value' };
const result = HTTPAsync.getRequest(url, params);
it('Should be promise', () => {
expect(result).toBeInstanceOf(Promise);
// HERE I WILL CHECK EXPECTED VALUES
return result.then(data => console.log(data));
});
});
});
What you could do is catch you request on sucess or Error, using superagent like this :
const request = require('superagent');
describe('HTTPAsync. test', () => {
it('Should be pfromise', done => {
request
.get('/your_url')
.then(res => {
// res.body, res.headers, res.status
//your own logic
done();
})
.catch(err => {
// err.message, err.response
//your own logic
done();
});
});
});

Categories