How can I export async await functions to use like a utils file? - node.js

I have a utils file where I have async await functions.
I am exporting these functions like this:
module.exports.pressing = pressing;
module.exports.login = login;
module.exports.logout = logout;
module.exports.getImage = getImage;
module.exports.decodeUnicodeCharacters = decodeUnicodeCharacters;
module.exports.initApp = initApp;
What I would like to achieve is that through the protractor configuration file I can call the functions of the utils file like this:
browser.params.utils.pressing(protractor.Key.DOWN);
What is the best way to do it?

Create a module and require anywhere you want to use it
utils.js
module.exports = {
pressing: function () {
// what it does
},
login: function () {
// what it does
},
logout: function () {
// what it does
},
getImage: function () {
// what it does
},
decodeUnicodeCharacters: function () {
// what it does
},
initApp: function () {
// what it does
},
};
then anywhere in project
let utils = require('PATH/TO/utils.js')
await utils.login();
Make it global
config
// ...
onPrepare() {
global.utils = {
login: function () {
// what it does
},
}
}
// ...
anywhere in project
await utils.login() // no need to require

Related

how to mock react-query useQuery in jest

I'm trying to mock out axios that is inside an async function that is being wrapped in useQuery:
import { useQuery, QueryKey } from 'react-query'
export const fetchWithAxios = async () => {
...
...
...
const response = await someAxiosCall()
...
return data
}
export const useFetchWithQuery = () => useQuery(key, fetchWithAxios, {
refetchInterval: false,
refetchOnReconnect: true,
refetchOnWindowFocus: true,
retry: 1,
})
and I want to use moxios
moxios.stubRequest('/some-url', {
status: 200,
response: fakeInputData,
})
useFetchWithQuery()
moxios.wait(function () {
done()
})
but I'm getting all sorts of issues with missing context, store, etc which I'm iterested in mocking out completely.
Don't mock useQuery, mock Axios!
The pattern you should follow in order to test your usages of useQuery should look something like this:
const fetchWithAxios = (axios, ...parameters) => {
const data = axios.someAxiosCall(parameters);
return data;
}
export const useFetchWithQuery = (...parameters) => {
const axios = useAxios();
return useQuery(key, fetchWithAxios(axios, ...parameters), {
// options
})
}
Where does useAxios come from? You need to write a context to pass an axios instance through the application.
This will allow your tests to look something like this in the end:
const { result, waitFor, waitForNextUpdate } = renderHook(() => useFetchWithQuery(..., {
wrapper: makeWrapper(withQueryClient, withAxios(mockedAxios)),
});
await waitFor(() => expect(result.current.isFetching).toBeFalsy());

Jest - mock function inside another module function

I'm trying to mock the return value (or implementation) of the functions inside another module's function with Jest. I need to test different scenarios (function throws error, returns null, returns an object, etc...)
That module (userService) returns a function that returns an object with that functions:
userService.js (I want to mock the return value of findUser & createUser)
...
function userService(userModel) {
async function findUser(userQuery) {
...
return foundUser;
}
async function createUser(user) {
...
return createdUser;
}
return { findUser, createUser };
}
module.exports = userService;
And I'm testing authStravaController, which uses that service functions:
authStravaController
...
const authStravaServiceRaw = require('../../services/authStravaService');
const userServiceRaw = require('../../services/userService');
const bikeServiceRaw = require('../../services/bikeService');
...
function authStravaController(userModel, bikeModel) {
const { findUser, createUser } = userServiceRaw(userModel); <-- WANT TO MOCK THAT FUNCTIONS
async function authStrava({ body: { authCode } }, res) {
...
try {
...
const findUserQuery = {
stravaUserId: stravaBasicUser.stravaUserId,
};
authUser = await findUser(findUserQuery); <-- MOCK THIS FUNCTION RETURN MULTIPLE TIMES
if (!authUser) {
resStatus = CREATED;
createdUser = await createUser(stravaBasicUser); <-- SAME
...
createdUser.bikes = createdBikes.map((bike) => bike._id);
createdUser.save();
authUser = { createdUser, createdBikes };
}
return handleResponseSuccess(res, resStatus, authUser);
} catch (authStravaError) {
return handleResponseError(res, authStravaError);
}
}
return { authStrava };
}
module.exports = authStravaController;
At the moment I've been able to mock the function return value just 1 time, and I can't find a way to rewrite it, so now I can only test 1 scenario
This code at the top of the file let me test 1 scenario
jest.mock('../../services/userService', () => () => ({
findUser: jest.fn().mockReturnValue(1),
createUser: jest.fn().mockReturnValue({ username: 'userName', save: jest.fn() }),
}));
I've tried to mock it in multiple ways and can't get it to work, how could I do it to test different return values:
findUser: jest.fn().mockReturnValue(1),
findUser: jest.fn().mockReturnValue(undefined),
findUser: jest.fn().mockReturnValue({user:'username'}),
etc...
Thanks!
I fixed it importing all the services outside the controller function, at the top of the file.
This way I can mock the returnValue of any function.

how to refer to a function when unit testing with NodeJS / Mocha

I'm making my first test with Mocha.
Dummy test is passing, but when I want to refer to my actual function that is in another file, it won't find it:
ReferenceError: main is not defined
I have a single index.js with :
async function main() {
function comparer(otherArray) {
return function (current) {
return otherArray.filter(function (other) {
return other.prm === current.prm && other.conso_prod === current.conso_prod
}).length === 0;
}
}
}
module.exports = main();
and in my test.js file, I do:
const {expect} = require('chai');
describe('Sum numbers', () => {
it('Compare 2 existing array', () => {
const meters = []
const perimeter = []
const onlyInMeters = meters.filter(main.comparer(perimeter));
expect(onlyInMeters).to.equal([]);
});
});
But when I refer to main.comparer, it can't find it:
ReferenceError: main is not defined
What am I forgetting? Sorry, I'm a NodeJS Noob!
It seems like you did not import the index.js file in test.js file. You are returning noting from main function as well.
Also, why are you exporting it like module.exports = main(); Instead you can do this:
// index.js
module.exports = {
comparer: (otherArray) => { ... }
}
// test.js
cosnt main = require('PATH_OF_index.js');
main.comparer();

Sinon Stub depedent class in node.js module

I have one class as below
nx-user.js
class NXUser {
constructor() {}
view(guid, data) {
//do something
}
}
Then I have user controller module as below which has dependency of NxUser class
userController.js
const userDb = new NXUser();
import NXUser from "../../../persistence/nx-user";
const allUsers = () => {
return userDb.view()
}
export {allUsers }
I have below code written for stubbing view function of NxUser class for controller unit tests. But its not working. It always calling actual one instated of stubbed one
userController-test.js
let userdb=NXUser();
describe("user controller", function () {
let stubValue = [{
"name": "Urvashi Parmar",
"email": "urvashi.parmar#nationalexpress.com"]}
it("Should create user", () => {
sinon.stub(userdb, 'create').resolves(stubValue);
userController.allUsers ().then((body) => {
expect(body[0].name).to.equal(stubValue .name);
done();
});
})
}
Because I can not comment yet, so I need to give full answer.
Confusion: at your userController-test.js, you are trying to test NXUser.create, while at file nx-user.js has no definition of create.
Assume: you are trying to test NXUser.view.
This example is created based on your code, and is working fine. Console log "Called" will not get called.
Highlight:
Stub NXUser view directly, not userdb.create;
I use async-await inside test.
const sinon = require('sinon');
const { expect } = require('chai');
class NXUser {
constructor() {}
view(guid, data) {
console.log('Called');
return new Promise((resolve) => resolve([]));
}
// Add this only for dummy.
create() {
return new Promise((resolve) => resolve([]));
}
}
const userController = {
allUsers() {
const userDb = new NXUser();
return userDb.view();
}
}
describe('user controller', function () {
// Suppose you test view user.
it('should view user', async function () {
const stubValue = [{
name: 'Urvashi Parmar',
email: 'urvashi.parmar#nationalexpress.com'
}];
// Suppose you stub method view and not create.
const stubUserDBView = sinon.stub(NXUser.prototype, 'view');
stubUserDBView.resolves(stubValue);
const body = await userController.allUsers();
expect(body).to.be.an('array').that.have.lengthOf(1);
expect(body[0]).to.have.property('name', stubValue[0].name);
// Restore stub.
stubUserDBView.restore();
});
});
$ npx mocha stackoverflow.js
user controller
✓ should view user
1 passing (11ms)
$
Hope this helps.

testing an actual returning value on javascript using jest

I have the following js function:
const modelUtils = {
modelingObj(obj, stringVal = ‘RE’) {
let newObj;
//my logic for setting value of newObj
return newObj;
};
export default modelUtils;
I want to test and see that based on a specific params I get a particular result, the issue is I’m always returning back an empty object.
Test.js
import modelUtils from '../modelUtils';
jest.unmock('../modelUtils');
describe(' testing modelUtils', () => {
let test;
const mockData = {
myProperty: [],
};
describe('testing modelingObj function', () => {
it('For my first test’, () => {
test = modelUtils.mockData, ‘TR’);
expect(test).toEqual({ myProperty: [] });
});
});
});

Resources