我正在运行节点版本16.15.0,并具有package.json依赖项:
"jest": "^28.1.0",
"mongodb-memory-server": "^8.6.0",
"mongoose": "^6.3.5",
我在一个mongoose.Schema模块中设置了一个User.js:
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()
})
})
顺便说一句:我还尝试用这个_id
表达式手动添加User.create
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中的代码在生产中工作,在这里我使用MOGOCommunityv5.0.7(在一个码头容器中)。
那么,为什么我在使用_id时不能访问MongoMemoryServer值呢?我有什么需要设置的吗?还是我做错了什么?
发布于 2022-10-22 02:52:08
我能复制它,它来自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();
});
});
如果您使用这个滑稽的配置。
clearMocks: true,
resetMocks: true,
resetModules: true,
您将得到TypeError:无法读取空(读'ObjectId')的属性,在这个示例中,我使用了"jest":"^29.2.1"
https://stackoverflow.com/questions/72524705
复制相似问题