As some part of my application needs connection to database I wanted to create tests that use mocks to avoid running special instance of database just for testing. That gave me a glimpse of how can I use mocks and I played with them a bit.
I wanted to test express router:
UserRouter.post("/users", async ({ body }: Request, res: Response) => {
try {
const userRepository = getCustomRepository(UserRepository);
const user = userRepository.create({ ...body } as User);
await userRepository.save(user);
res.send(user.toJSON());
} catch (error) {
res.status(400).send();
}
});
To do so I created mocks:
jest.mock("typeorm", () => ({
__esModule: true,
getCustomRepository: jest.fn(),
PrimaryGeneratedColumn: jest.fn(),
Column: jest.fn(),
CreateDateColumn: jest.fn(),
UpdateDateColumn: jest.fn(),
Entity: jest.fn(),
EntityRepository: jest.fn(),
Repository: jest.fn(),
}));
const getCustomRepositoryMock = mocked(getCustomRepository);
const MockedRepository = {
create: jest.fn(),
save: jest.fn(),
};
const MockedEntity = {
toJSON: jest.fn(),
};
beforeEach(() => {
jest.resetAllMocks();
getCustomRepositoryMock.mockReturnValueOnce(MockedRepository);
});
Then instead of passing and requiring actual data to be return I relayed of testing whether mocks were used, what data were passed to their calls etc. Here is an example:
it("should call save on UserRepository with value returned by call create on UserRepository", async () => {
MockedRepository.create.mockReturnValue(MockedEntity);
await request(app).post(path).send();
expect(MockedRepository.save).toBeCalledWith(MockedEntity);
});
Commit with all my tests is here.