我正在尝试将单元测试添加到我的node express应用程序中。该应用程序使用sequelize with sqlite作为它的orm/数据库。我正在尝试直接对我的一个最简单的控制器进行单元测试(甚至还没有尝试用supertest测试路由)
我能够得到一个基本的成功测试,我遇到的问题是,由于我的控制器导入了我的sequelize用户模型,它也导入了Sequelize的示例化。这导致sequelize在执行测试时试图连接到数据库。测试在所有数据库的东西发生之前执行,因此最后我的结果是很多“测试完成后无法记录,”因为Sequelize仍在尝试连接和记录,一些来自sequelize模块本身,另一些来自我的代码连接和sync()
ing数据库。
如果我在我的控制器中删除了模型的导入和使用,我就不再有这些问题了,所以很明显导入模型会导致所有这些调用初始化sequelize。我如何让Jest等待所有异步进程完成,或者只是阻止sequelize初始化(我实际上不需要数据库连接,我将用模拟测试它们)
测试结果如下
describe('testing user registration', () => {
let mRes: Response<any, Record<string, any>>;
let mNext;
beforeAll(()=>{
mRes = {
status: jest.fn().mockReturnThis(),
json: jest.fn()
}
mNext = jest.fn(err => err)
jest.spyOn(UserModel, 'create').mockResolvedValue(createdUser)
})
afterAll(()=>{
jest.resetAllMocks();
})
test('with invalid email', async () => {
const result = await registerUser(mReqInvalidEmail, mRes, mNext);
expect(mNext).toBeCalledWith(invalidBodyError)
})
})
下面是控制器的外观:
const registerUser = async(req:Request,res:Response,next:NextFunction) : Promise<Promise<Response> | void> => {
const {body} = req
const {email, role} = body;
if(!isValidEmail(email) || !isValidRole(role)){
const error = createError(
400,
'Invalid body, please provide a valid email address a role of oneOf[\"user\",\"super\"]',
{
body: {
email: 'a valid email string',
role: 'string, oneOf [user, super]'
}
}
);
return next(error);
}
const password = generatePassword()
const hash = hashPassword(password)
const user = await User.create({email, role, password:hash}).catch((err: Error) : Error => {
return createError(500, 'woopsie', err)
})
if(user instanceof Error){
return next(user)
}
return res.status(200).json({
email,
role,
password
});
}
型号:
import {sqlzDB} from "../../database/db";
const User = sqlzDB.define('User',
{
...myfields, not including to save space
}, {
options
})
最后,sequelize被初始化(声明sqlzDB)。这是所有正在运行的代码,我需要等待它完成,或者阻止它被调用!
const {Sequelize} = require('sequelize');
export const sqlzDB = new Sequelize({
dialect: 'sqlite',
storage: 'database/db.sqlite'
});
sqlzDB.authenticate()
.then(():void => {
console.log('Connection to database established successfully.');
}).catch((err : Error): void => {
console.log('Unable to connect to the database: ', err);
})
sqlzDB.sync().then(()=>{
console.log('Sequelize Synced')
})
我的测试通过得很好。注意,对于我写的测试,我实际上还不需要模拟,因为我只是想让设置正确工作。
我已经尝试了我在这里看到的建议,比如在我的测试后调用await new Promise(setImmediate);
,或者也关闭与sqlzDB.close()
的连接,这会导致一些不同的问题(它关闭了连接,但仍然试图记录)
所以我不知道在这一点上如何处理这个问题!很抱歉这个长的问题,并感谢谁花时间阅读这篇文章!
1条答案
按热度按时间swvgeqrz1#
您可以尝试一个技巧来避免此问题:在afterAll中关闭连接