Nestjs 猫鼬单元测试:类型错误: <functionName> 不是一个函数



根据这个github repo,我们想测试一个用户样本
考虑这个测试文件:

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', 'jack@gmail.com'),
];
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);
});

,这是用户文档文件:

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;
}

第1次和第2次测试都通过了,但第3次会抛出:

TypeError: this.userModel.findById is not a function该接口由mongoose文档扩展而来,findById函数在测试中无法识别。

这是github可用的repo。因此,任何帮助都将不胜感激。

请注意,在UserModel模拟中,您没有为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
},
},

在你模拟的方法集中需要有一个findById方法。

顺便说一下,我需要通过new调用构造函数,所以我更喜欢定义这样的模拟类:

class UserModelMock {
constructor(private data) {}
new = jest.fn().mockResolvedValue(this.data);
save = jest.fn().mockResolvedValue(this.data);
static find = jest.fn().mockResolvedValue(mockUser());
static create = jest.fn().mockResolvedValue(mockUser());
static remove = jest.fn().mockResolvedValueOnce(true);
static exists = jest.fn().mockResolvedValue(false);
static findOne = jest.fn().mockResolvedValue(mockUser());
static findByIdAndUpdate = jest.fn().mockResolvedValue(mockUser());
static findByIdAndDelete = jest.fn().mockReturnThis();
static exec = jest.fn();
static deleteOne = jest.fn().mockResolvedValue(true);
static findById = jest.fn().mockReturnThis();
}

最新更新