I am currently on a project and i need to mock
a certain constructor
class
prototype
to run test so it doesn't deal directly with my database
. I already tried researching and discovered i need to import
the module
into my mock
file and then export
it to my test
file and use jest.setMock()
to replace the module in my test.js
file. Below is the code to what i have tried.
I have an Admin
constructor
class
with a delete function in its prototype
responsible for deleting from db
admin.js
function Admin(username, email, password, access) {
Users.call(this, username, email, password, access);
}
Admin.constructor = Admin;
Admin.prototype.deleteSingleUser = function(id, accountType) {
this.id = id;
this.accountType = accountType;
let response = "";
if(this.accountType === "admin") {
for(let i in dbData.admin) {
if(dbData.admin[i].id === this.id) {
dbData.admin.splice(i, 1);
fs.writeFileSync('db.json', JSON.stringify(dbData, null, 2));
console.log(dbData.admin);
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
}
else if(this.accountType === "user") {
for(let i in dbData.users) {
if(dbData.users[i].id === this.id) {
dbData.users.splice(i, 1);
fs.writeFileSync('db.json', JSON.stringify(dbData, null, 2));
console.log(dbData.users);
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
}
else {
response = "Kindly use a valid account type";
}
console.log(response);
return response;
};
Then in my __mocks__
directory i have an admin.js
file containing a mock
database and my mock
delete code
__mocks__/admin.js
//Imported the admin.js
let Admin = require("../admin");
//Created a mock database
let mockDb = {
"users": [
{
"id": 1,
"username": "aaa",
"email": "[email protected]",
"password": "aaa",
"access": "user"
}
],
"admin": [
{
"id": 1,
"username": "bbb",
"email": "[email protected]",
"password": "bbb",
"access": "admin"
}
]
}
//My mock delete function
Admin.prototype.deleteSingleUser = function(id, accountType) {
this.id = id;
this.accountType = accountType;
let response = "";
if (this.accountType === "admin") {
if(mockDb.admin[0].id === this.id) {
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
else if (this.accountType === "user") {
if(mockDb.users[0].id === this.id) {
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
console.log("Its using the mock");
return response;
};
module.exports = Admin;
Then in my __test__
folder i have a test.js
file with my test cases
__test__/test.js
const Admin = require("../admin");
jest.setMock("Admin", require("../__mocks__/admin"));
test("Should check if admin can delete with a wrong id", () => {
let response = Admin.prototype.deleteSingleUser(0, "user");
expect(response).toBe("There is no user registered with this ID");
});
test("Should check if admin can delete a user", () => {
let response = Admin.prototype.deleteSingleUser(1, "user");
expect(response).toBe("Account successfully deleted");
});
Neither of the test cases pass but both throw
an error
saying
Test suite failed to run
Cannot find module 'Admin' from 'test.js'
2 | const Users = require("../main");
3 | const Admin = require("../admin");
4 | jest.setMock("Admin", require("../mocks/admin"));
| ^
5 | const order = require("../order");
6 | let mocks = require("../mocks/admin");
7 | let dbData = JSON.parse(fs.readFileSync('db.json'));
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:229:17)
at Object.setMock (test/test.js:4:6)
I feel i am not doing something right but i can't seem to point it out. Please what is the issue and how do i fix it? Thanks.
I am currently on a project and i need to mock
a certain constructor
class
prototype
to run test so it doesn't deal directly with my database
. I already tried researching and discovered i need to import
the module
into my mock
file and then export
it to my test
file and use jest.setMock()
to replace the module in my test.js
file. Below is the code to what i have tried.
I have an Admin
constructor
class
with a delete function in its prototype
responsible for deleting from db
admin.js
function Admin(username, email, password, access) {
Users.call(this, username, email, password, access);
}
Admin.constructor = Admin;
Admin.prototype.deleteSingleUser = function(id, accountType) {
this.id = id;
this.accountType = accountType;
let response = "";
if(this.accountType === "admin") {
for(let i in dbData.admin) {
if(dbData.admin[i].id === this.id) {
dbData.admin.splice(i, 1);
fs.writeFileSync('db.json', JSON.stringify(dbData, null, 2));
console.log(dbData.admin);
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
}
else if(this.accountType === "user") {
for(let i in dbData.users) {
if(dbData.users[i].id === this.id) {
dbData.users.splice(i, 1);
fs.writeFileSync('db.json', JSON.stringify(dbData, null, 2));
console.log(dbData.users);
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
}
else {
response = "Kindly use a valid account type";
}
console.log(response);
return response;
};
Then in my __mocks__
directory i have an admin.js
file containing a mock
database and my mock
delete code
__mocks__/admin.js
//Imported the admin.js
let Admin = require("../admin");
//Created a mock database
let mockDb = {
"users": [
{
"id": 1,
"username": "aaa",
"email": "[email protected]",
"password": "aaa",
"access": "user"
}
],
"admin": [
{
"id": 1,
"username": "bbb",
"email": "[email protected]",
"password": "bbb",
"access": "admin"
}
]
}
//My mock delete function
Admin.prototype.deleteSingleUser = function(id, accountType) {
this.id = id;
this.accountType = accountType;
let response = "";
if (this.accountType === "admin") {
if(mockDb.admin[0].id === this.id) {
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
else if (this.accountType === "user") {
if(mockDb.users[0].id === this.id) {
response = "Account successfully deleted";
}
else {
response = "There is no user registered with this ID";
}
}
console.log("Its using the mock");
return response;
};
module.exports = Admin;
Then in my __test__
folder i have a test.js
file with my test cases
__test__/test.js
const Admin = require("../admin");
jest.setMock("Admin", require("../__mocks__/admin"));
test("Should check if admin can delete with a wrong id", () => {
let response = Admin.prototype.deleteSingleUser(0, "user");
expect(response).toBe("There is no user registered with this ID");
});
test("Should check if admin can delete a user", () => {
let response = Admin.prototype.deleteSingleUser(1, "user");
expect(response).toBe("Account successfully deleted");
});
Neither of the test cases pass but both throw
an error
saying
Test suite failed to run
Cannot find module 'Admin' from 'test.js'
2 | const Users = require("../main");
3 | const Admin = require("../admin");
4 | jest.setMock("Admin", require("../mocks/admin"));
| ^
5 | const order = require("../order");
6 | let mocks = require("../mocks/admin");
7 | let dbData = JSON.parse(fs.readFileSync('db.json'));
at Resolver.resolveModule (node_modules/jest-resolve/build/index.js:229:17)
at Object.setMock (test/test.js:4:6)
I feel i am not doing something right but i can't seem to point it out. Please what is the issue and how do i fix it? Thanks.
Share Improve this question asked Apr 20, 2019 at 17:53 codebarzcodebarz 3271 gold badge8 silver badges28 bronze badges3 Answers
Reset to default 3You don't need to use jest.setMock
at all.
You just need to activate the manual mock you created for your user module by doing this:
jest.mock('../admin'); // <= activate the manual mock
Details
The docs for jest.setMock
state that it should only be used on "extremely rare occasions" when "even a manual mock isn't suitable for your purposes" and adds that it is "remended to use jest.mock()
instead."
In this case you aren't doing anything that would require jest.setMock
so best practice is to activate your manual mock with jest.mock
.
Your code seems alright. You just need to set your jest.setMock()
to point to the right file.
jest.setMock()
takes two parameters jest.setMock(moduleName, moduleExports)
. The moduleName
should point to the file containing the module
your are mocking and moduleExports
to the file containing your mock module. In other words, change in your
__test__/test.js
jest.setMock("Admin", require("../__mocks__/admin"));
to
jest.setMock("../admin", require("../__mocks__/admin"));
And you should be fine.
to use mock() method you have to give function as a second parameter so you can use the following code.
jest.mock("../admin", () => require("../__mocks__/admin"));