Hi I am using sequelize ORM with Postgres database for this node.js express.js app. As for testing I am using mocha, chai and sinon.
I am trying to complete a test for a class's method. The class instant i call it userService and the method is findOneUser .. This method has got an argument id .. So in this moment I want to test for a throw error the test works if I dont put an argument. That means this test is obviously not complete.
Here is the class method I want to test
userService.js
module.exports = class UserService {
async findOneUser(id) {
try {
const user = await User.findOne({ where: { id: id } }); // if null is returned error is thrown
if (!user) {
throw createError(404, "User not found");
}
return user;
} catch (err) {
throw err
}
}
}
And here is my test code
userService.spec.js
describe.only("findOne() throws error", () => {
let userResult;
const error = customError(404, "User not found"); // customError is a function where I am throwing both status code and message
before("before hook last it block issue withArgs" , async () => {
// mockModels I have previously mocked all the models
mockModels.User.findOne.withArgs({ where: { id: fakeId } }).resolves(null); // basically have this called and invoked from calling the method that it is inside of based on the argument fakeId
userResult = sinon.stub(userService, "findOneUser").throws(error); // this is the class instances method I wonder how to test it withArguments anything I try not working but SEE BELOW COMMENTS
});
after(() => {
sinon.reset()
});
it("userService.findOneUser throws error works but without setting arguments ", () => {
expect(userResult).to.throw(error);
});
/// this one below still not working
it("call User.findOne() with incorrect parameter,, STILL PROBLEM ", () => {
expect(mockModels.User.findOne).to.have.been.calledWith({ where: { id: fakeId } });
})
});
But for the method of my class findOneUser has an argument (id) how can I pass that argument into it where I am stubbing it?
Or even any ideas on how to fake call the class method?? I want both it blocks to work
EDIT
I forgot to mention I have stubbed the mockModels.User already and that was done before the describe block
const UserModel = {
findByPk: sinon.stub(),
findOne: sinon.stub(),
findAll: sinon.stub(),
create: sinon.stub(),
destroy: sinon.stub()
}
const mockModels = makeMockModels( { UserModel } );
// delete I am only renaming UserModel to User to type things quicker and easier
delete Object.assign(mockModels, {['User']: mockModels['UserModel'] })['UserModel']
const UserService = proxyquire(servicePath, {
"../models": mockModels
});
const userService = new UserService();
const fakeUser = { update: sinon.stub() }