我試圖將單元測驗添加到我的 node express 應用程式中。該應用程式使用 sqlite 作為其 orm/database 的 sequelize。我正在嘗試直接對我最簡單的控制器之一進行單元測驗(甚至還沒有嘗試使用 supertest 測驗路由)
我能夠獲得一個基本的成功測驗,我遇到的問題是,由于我的控制器匯入了我的 sequelize User 模型,它還匯入了 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()導致一些不同問題的連接(它關閉連接但仍嘗試記錄)
所以我現在不知道如何解決這個問題!很抱歉這個問題很長,感謝花時間閱讀本文的人!
uj5u.com熱心網友回復:
您可以嘗試一個技巧來避免此問題:在 afterAll 中關閉連接
afterEach(() => { // reset mock should be in afterEach
jest.resetAllMocks();
});
afterAll(async ()=>{
await sqlzDB.close();
await new Promise(res => setTimeout(res, 500)); // avoid jest open handle error
});
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/523263.html
