I am using typescript with typeORM and I have a jest test that looks as followed:
test('add test', async () => {
testRepoMock = {
innerTestRepo: ({
findOne: jest.fn().mockReturnValue(null),
create: jest.fn().mockReturnValue({ id: 2 }),
} as unknown) as Repository<ValuesModel>,
};
TestService.addvalue(id, testRepoMock);
expect(testRepoMock.innerTestRepo.findOne).toHaveBeenCalledTimes(1);
expect(testRepoMock.innerTestRepo.create).toHaveBeenCalledTimes(1);
});
The function I'm testing looks like this:
static async addvalue(
id: number,
repos?: { innerTestRepo: Repository<ValuesModel> },
): Promise<Values> {
let repo;
if (repos) {
// basically use our mocks if this is a unit test
repo = repos.innerTestRepo;
} else {
repo = await SqlDb.getRepository(ValuesModel);
}
let perms = await repo.findOne({ id });
if (!perms) {
perms = repo.create();
perms = {
...perms,
};
await repo.save(perms);
}
return perms;
}
What I cannot figure out is that the expect(testRepoMock.innerTestRepo.create).toHaveBeenCalledTimes(1);
keeps reporting that testRepoMock.innerTestRepo.create
was never called, even though I can log that perms is set to {id:2}
via the mock and that the if statement is indeed entered.
I even checked what happened if I move the repo.create out of that if statement as a sanity check and then the test passes, so it looks like something about the scope of the if statement confuses jest such that it does not realize that create has been called.
You need to add await
when you call addValue
, otherwise your expect lines will be executed before the functions are actually executed
test('add test', async () => {
testRepoMock = {
innerTestRepo: ({
findOne: jest.fn().mockReturnValue(null),
create: jest.fn().mockReturnValue({ id: 2 }),
} as unknown) as Repository<ValuesModel>,
};
await TestService.addvalue(id, testRepoMock);
expect(testRepoMock.innerTestRepo.findOne).toHaveBeenCalledTimes(1);
expect(testRepoMock.innerTestRepo.create).toHaveBeenCalledTimes(1);
});