monommemoryserver或mongoose在Jest中没有提供Schema _id



我正在运行节点版本16.15.0,并有包。json依赖性:

"jest": "^28.1.0",
"mongodb-memory-server": "^8.6.0",
"mongoose": "^6.3.5",

我有一只猫鼬。在User.js模块中设置Schema:

import mongoose from 'mongoose'
import validator from 'validator'
import bcrypt from 'bcryptjs'
import jwt from 'jsonwebtoken'
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: [true, 'Please provide name'],
minlength: 3,
maxlength: 20,
trim: true,
},
email: {
type: String,
required: [true, 'Please provide email'],
validate: {
validator: validator.isEmail,
message: 'Please provide a valid email',
},
unique: true,
},
password: {
type: String,
required: [true, 'Please provide password'],
minlength: 6,
select: false,
},
role: {
type: String,
trim: true,
maxlength: 20,
default: 'PLAYER',
},
})
UserSchema.pre('save', async function () {
// console.log(this.modifiedPaths())
if (!this.isModified('password')) return
const salt = await bcrypt.genSalt(10)
this.password = await bcrypt.hash(this.password, salt)
})
UserSchema.methods.createJWT = function () {
return jwt.sign({ userId: this._id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_LIFETIME,
})
}
UserSchema.methods.comparePassword = async function (candidatePassword) {
const isMatch = await bcrypt.compare(candidatePassword, this.password)
return isMatch
}
export default mongoose.model('User', UserSchema)

(注意UserSchema.methods.createJWT = function,因为它在下面的测试中)

最后是一个简单的Jest测试(我刚刚开始使用Jest):

import mongoose from 'mongoose'
import dotenv from 'dotenv'
import { MongoMemoryServer } from 'mongodb-memory-server'
import User from '../../models/User.js'
describe('User Schema suite', () => {
dotenv.config()
const env = process.env
var con, mongoServer
beforeAll(async () => {
mongoServer = await MongoMemoryServer.create()
con = await mongoose.connect(mongoServer.getUri(), {})
jest.resetModules()
process.env = { ...env }
})
afterAll(async () => {
if (con) {
con.disconnect()
}
if (mongoServer) {
await mongoServer.stop()
}
process.env = env
})
test('should read the environment vars', () => {
expect(process.env.JWT_SECRET).toBeTruthy()
expect(process.env.JWT_SECRET).toEqual('?E(H+MbQeThWmYq3t6w9z$C&F)J@NcRf')
expect(process.env.JWT_LIFETIME).toBeTruthy()
expect(process.env.JWT_LIFETIME).toEqual('1d')
})
test('should create and sign a good token', async () => {
const user = await User.create({
name: 'Mike',
email: 'some.user@bloodsuckingtechgiant.com',
password: 'secret',
})
expect(user.createJWT()).toBeTruthy()
})
})

BTW:我还试图用这个User.create表达式手动添加_id

const user = await User.create({
_id: '62991d39873ec2778e34f114',
name: 'Mike',
email: 'some.user@bloodsuckingtechgiant.com',
password: 'secret',
})

但这并没有什么区别。

第一个测试通过,但第二个测试失败,出现以下错误:

mike@mike verser % npm test
> verser@1.0.0 test
> jest --testEnvironment=node --runInBand ./tests
FAIL  tests/models/User.test.js
● User Schema suite › should create and sign a good token
TypeError: Cannot read properties of null (reading 'ObjectId')
at Object.<anonymous> (node_modules/mongoose/lib/types/objectid.js:13:44)
at Object.<anonymous> (node_modules/mongoose/lib/utils.js:9:18)

Test Suites: 1 failed, 1 skipped, 1 of 2 total
Tests:       1 failed, 1 skipped, 1 passed, 3 total
Snapshots:   0 total
Time:        1.127 s, estimated 2 s
Ran all test suites matching /./tests/i.

User.js中的代码在生产中工作,我使用Mongo Community v5.0.7(在docker容器中)。

那么为什么我不能访问_id值,当我使用MongoMemoryServer代替?有什么需要我设置的吗?还是我还做错了什么?

所以,最终的问题是Jest无法处理我在ES6中创建的各种箭头函数和导入项目。在考虑了至少一百种不同的答案之后,包括babel或向包中的Jest脚本调用添加参数。Json,除了在非常简单的测试用例中,它们都不起作用……我放弃了杰斯特,选择了摩卡。我现在走得更远了。

简而言之:如果你正在使用ES6 -避免Jest。

我被告知,有很多工具可以让TypeScript和Jest一起工作,但我不打算重写我的整个项目。

我能够复制它,它来自jest.config.js

我从

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['js', 'json', 'ts'],
rootDir: 'src',
testRegex: '.*\.spec\.ts$',
collectCoverageFrom: ['**/*.(t|j)s'],
collectCoverage: true,
coverageDirectory: '../coverage',
clearMocks: true,
resetMocks: true,
resetModules: true,
};

/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
moduleFileExtensions: ['js', 'json', 'ts'],
rootDir: 'src',
testRegex: '.*\.spec\.ts$',
collectCoverageFrom: ['**/*.(t|j)s'],
collectCoverage: true,
coverageDirectory: '../coverage'
};

错误消失。

你可以试试下面这个测试

import { Connection, connect, Schema } from 'mongoose';
import { MongoMemoryServer } from 'mongodb-memory-server';
describe('TagController Unit tests', () => {
let mongod: MongoMemoryServer;
let mongoConnection: Connection;
beforeEach(async () => {
mongod = await MongoMemoryServer.create();
const uri = mongod.getUri();
mongoConnection = (await connect(uri)).connection;
mongoConnection.model('SchemaTest', new Schema({ test: String }));
});
afterAll(async () => {
await mongoConnection.dropDatabase();
await mongoConnection.close();
await mongod.stop();
});
afterEach(async () => {
const { collections } = mongoConnection;
// eslint-disable-next-line no-restricted-syntax, guard-for-in
for (const key in collections) {
const collection = collections[key];
// eslint-disable-next-line no-await-in-loop
await collection.deleteMany({});
}
});
it('Create new Tag', async () => {
expect({}).toBeDefined();
});
});

如果您使用这个jest配置。

clearMocks: true,
resetMocks: true,
resetModules: true,

你会得到TypeError: Cannot read properties of null (reading 'ObjectId')对于这个例子,我使用了"jest"; "^29.2.1">

相关内容

  • 没有找到相关文章

最新更新