问题描述
对我的 nodejs 后端的一些请求是 Ajax 请求,对于这些路由,我使用令牌身份验证,“令牌保存在 fs 上”。
我使用 jest-supertest 进行测试。
如果我直接测试保存令牌的函数(模拟 fs)它可以工作。
功能:
async function savetoken(token) {
try{
const err = await promisify(fs.writeFile)(
'/opt/app/tmp/token.txt',token,{encoding: 'utf8',flag: 'w'}
)
if(err) throw Error('error in close: ',err)
else return true
测试://有效
const mock = require('mock-fs');
const { savetoken } = require('../token')
const { readFile } = require('fs').promises
it('makes sure the token is saved',async() => {
const token = 'theIsThetoken'
mock({
'/opt/app/tmp/token.txt': ''
});
await savetoken(token)
const dts = await readFile('/opt/app/tmp/token.txt','utf8')
mock.restore();
expect(dts).toEqual(token)
})
但我不想运行单元测试,我想检查完整的请求。问题是,如果我模拟路径的测试和文件崩溃的其他测试。看起来它在所有测试中都嘲笑 fs ......?
路由逻辑
exports.getAddReview = async(req,res,next) => {
const token = Math.random().toString(36).split('.')[1].slice(0,10)
try {
const hash = await encrypt(token)
const tokenSaved = await savetoken(token)
if(!tokenSaved) throw Error(REVIEW_CT,' - token is not save')
res.render('tprmain/edit-review',{
pageTitle: 'edit-review',path: '/edit-review',editing: false,token: hash
})
} catch(e) {
next(new ProcessError('A system error occured,please try again'))
}
}
测试:
it('save token',async() => {
const resp = await global.signin()
// mock({
// '/opt/app/tmp/token.txt': ''
// });
await resp
.get('/add-review')
.send()
.expect(200)
// mock.restore();
})
如果我像上面那样运行测试,我会得到这个错误,这是正常的 fs 不是模拟的。
error from save token: [Error: ENOENT: no such file or directory,open '/opt/app/tmp/token.txt'] {
所以我取消了模拟此请求的 fs 的注释,但随后所有其他测试(在同一测试文件上)崩溃
// mock({
// '/opt/app/tmp/token.txt': ''
// });
错误是
FAIL controllers/__test__/carsCt.test.js
● Test suite Failed to run
ENOENT: no such file or directory,open '/home/jerome/Documents/code/tprSiang/api/controllers/__test__/carsCt.test.js'
at runTestInternal (node_modules/jest-runner/build/runTest.js:202:27)
FAIL controllers/__test__/picsmainCt.test.js
● Test suite Failed to run
ENOENT: no such file or directory,open
'/home/jerome/Documents/code/tprSiang/api/controllers/__test__/picsmainCt.test.js'
at runTestInternal (node_modules/jest-runner/build/runTest.js:202:27)
etc...............
如果有人有解决方案,谢谢,因为我想测试完整的路线,而不仅仅是功能。
================== 在这里查看完整的测试设置 ==========
jest 设置文件
const { MongoMemoryServer } = require('mongodb-memory-server')
const mongoose = require('mongoose')
const session = require('supertest-session')
const keys = require('../config/keys')
const app = require('../index')
let mongo
beforeAll(async() => {
// process.env.NODE_ENV = 'test'
mongo = new MongoMemoryServer()
const mongoUri = await mongo.getUri()
await mongoose.connect(mongoUri,{
useNewUrlParser: true,useUnifiedTopology: true
})
})
beforeEach(async() => {
const collections = await mongoose.connection.db.collections()
for(let c of collections){
await c.deleteMany({})
}
})
afterall(async() => {
await mongo.stop()
await mongoose.connection.close()
})
// afterEach(async() => {
// mock.restore();
// })
global.signin = async() => {
let testSession = session(app)
return await new Promise((resolve,reject) => {
testSession.post('/postsignin')
.set('Content-Type','application/x-www-form-urlencoded')
.send({
name: keys.adminName1,password: keys.adminPasswordClear
})
.end(err => {
if(err) reject(err)
resolve(testSession)
})
})
}
无法模拟 fs 的测试文件
const app = require('../../index')
const session = require('supertest-session')
const keys = require('../../config/keys')
const Review = require('mongoose').model('Review')
const mock = require('mock-fs');
// test get reviews
it('makes sure getReviews need authentification',async() => {
await session(app)
.get('/reviews')
.send()
.expect('Location','/admin/getsignin')
})
it('get all the reviews',async() => {
const resp = await global.signin()
await resp
.get('/reviews')
.send()
.expect(200)
})
// test postAddReviews,all token logic is tested separatly
it('add some correct reviews',async() => {
const dataSample = new Review({
name:'addReview',comment:'comment addReview',picUrl:'http://urlPicture.com',quand: Date.Now()
})
const savedDts = await dataSample.save()
const reviewsDB = await Review.find()
expect(dataSample.name).toEqual(reviewsDB[0].name)
expect(dataSample.comment).toEqual(reviewsDB[0].comment)
expect(dataSample.picUrl).toEqual(reviewsDB[0].picUrl)
})
// test the mock,the mock restore is in afterEach() in the setup.js file
// it('test getAddReview',async() => {
// const resp = await global.signin()
// mock({
// '/opt/app/tmp/token.txt': ''
// });
//
// await resp
// .get('/add-review')
// .send()
// .expect(200)
// })
// does not work as can test the token in query
// it('add some incorrect picUrl field',async() => {
// const resp = await global.signin()
//
// const dataSample = {
// name:'addReview',// comment:'comment addReview',// nopicUrlfield:'http://urlPicture.com',// quand: Date.Now()
// }
//
// const response = await resp
// .post('/add-review')
// .set('Content-Type','application/x-www-form-urlencoded')
// .send(JSON.stringify(dataSample))
// .expect(417)
// })
// test postEditReview
it('makes sure postEditReviews need authentification',async() => {
await session(app)
.get('/edit-review/:id')
.send()
.expect('Location','/admin/getsignin')
})
it('update a review',async() => {
const resp = await global.signin()
// save/set original review
const dataSample = new Review({
name:'addReview',quand: Date.Now()
})
const reviewSaved = await dataSample.save()
// create updated review
const updatedDatas = {
name:'addReview updated',comment:'comment addReview updated',picUrl:'http://updated.com',quand: Date.Now()
}
// save updated datas
await resp
.post(`/edit-review/${reviewSaved._id}`)
.set('Content-Type','application/x-www-form-urlencoded')
// .send(JSON.stringify(updatedDatas))
.send(updatedDatas)
.expect(302)
// get the reviews
const reviewsDB = await Review.find()
expect(updatedDatas.name).toEqual(reviewsDB[0].name)
expect(updatedDatas.comment).toEqual(reviewsDB[0].comment)
})
// test getDeleteReview
it('makes sure the getDeleteReview route need auth',async() => {
await session(app)
.get('/delete-review/67546')
.send()
.expect('Location','/admin/getsignin')
})
it('delete a review',quand: Date.Now()
})
const reviewSaved = await dataSample.save()
// delete the review
await resp
.get(`/delete-review/${reviewSaved._id}`)
.send()
// get the reviews
const reviewsDB = await Review.find()
expect(reviewsDB.length).toEqual(0)
})
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)