according to this github repo we want to test a user sample
consider this test file :
const mockUser = (
phone = '9189993388',
password = 'jack1234',
id = '3458',
): User => ({
phone,
password,
_id: new Schema.Types.ObjectId(id),
});
const mockUserDoc = (mock?: Partial<User>): Partial<IUserDocument> => ({
phone: mock?.phone || '9189993388',
password: mock?.password || 'jack1234',
_id: mock?._id || new Schema.Types.ObjectId('3458'),
});
const userArray = [
mockUser(),
mockUser('Jack', '9364445566', '[email protected]'),
];
const userDocArray = [
mockUserDoc(),
mockUserDoc({
phone: '9364445566',
password: 'jack1234',
_id: new Schema.Types.ObjectId('342'),
}),
mockUserDoc({
phone: '9364445567',
password: 'mac$',
_id: new Schema.Types.ObjectId('425'),
}),
];
describe('UserRepository', () => {
let repo: UserRepository;
let model: Model<IUserDocument>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
UserRepository,
{
provide: getModelToken('User'),
// notice that only the functions we call from the model are mocked
useValue: {
new: jest.fn().mockResolvedValue(mockUser()),
constructor: jest.fn().mockResolvedValue(mockUser()),
find: jest.fn(),
findOne: jest.fn(),
update: jest.fn(),
create: jest.fn(),
remove: jest.fn(),
exec: jest.fn(),
},
},
],
}).compile();
repo = module.get<UserRepository>(UserRepository);
model = module.get<Model<IUserDocument>>(getModelToken('User'));
});
it('should be defined', () => {
expect(repo).toBeDefined();
});
afterEach(() => {
jest.clearAllMocks();
});
it('should return all users', async () => {
jest.spyOn(model, 'find').mockReturnValue({
exec: jest.fn().mockResolvedValueOnce(userDocArray),
} as any);
const users = await repo.findAll({});
expect(users).toEqual(userArray);
});
it('should getOne by id', async () => {
const userId = '324';
jest.spyOn(model, 'findOne').mockReturnValueOnce(
createMock<Query<IUserDocument, IUserDocument>>({
exec: jest.fn().mockResolvedValueOnce(
mockUserDoc({
_id: new Schema.Types.ObjectId(userId),
}),
),
}) as any,
);
const findMockUser = mockUser('Tom', userId);
const foundUser = await repo.findById(new Schema.Types.ObjectId(userId));
expect(foundUser).toEqual(findMockUser);
});
and this is the user document file:
export interface IUserDocument extends Document {
_id: Schema.Types.ObjectId;
email?: string;
password: string;
firstName?: string;
lastName?: string;
nationalCode?: string;
phone: string;
address?: string;
avatar?: string;
}
the 1th and 2nd test are passed but the third one throws:
TypeError: this.userModel.findById is not a function
also the interface is extended from mongoose Document, the findById
function is not recognized in the test.
this is the github repo available. so any help will be appreciated.
CodePudding user response:
Notice how in your UserModel
mock you don't provide a mock function for findById
{
provide: getModelToken('User'),
// notice that only the functions we call from the model are mocked
useValue: {
new: jest.fn().mockResolvedValue(mockUser()),
constructor: jest.fn().mockResolvedValue(mockUser()),
find: jest.fn(),
findOne: jest.fn(),
update: jest.fn(),
create: jest.fn(),
remove: jest.fn(),
exec: jest.fn(),
findById: jest.fn(), // <-------------- Add this
},
},
There needs to be a findById
method in that set of methods that you mock.