簡體   English   中英

使用chai-http與mocha-chai進行測試期間的UnhandledPromiseRejectionWarning

[英]UnhandledPromiseRejectionWarning during testing with mocha-chai using chai-http

制作我的第一個Express應用程序時,我試圖編寫一個針對api端點的測試,並使用數據結構作為數據庫的占位符,但是即使測試“通過”,也仍然在控制台中出現錯誤,如圖所示。

控制台輸出

  import chai from 'chai'; import { app } from '../app'; import http from 'chai-http'; let expect = chai.expect; //test I am having problems with it('should get a single todo at "/api/v1/todos/:id" with GET/id', () => { return chai .request(app) .post('/api/v1/todos') .send({ title: 'Breakfast', description: 'Breakfast alone' }) .then(resPost => { expect(resPost).to.have.status(201); chai .request(app) .get('/api/v1/todos/2') .then(res => { expect(res).to.have.status(200); expect(res).to.be.json; expect(res.body).to.be.an('object'); expect(res.body) .to.have.property('success') .eql('true'); expect(res.body) .to.have.property('message') .equal('todo retrieved successfully'); expect(res.body.todo).to.be.an('object'); expect(res.body.todo) .to.have.property('id') .equal(1); expect(res.body.todo) .to.have.property('title') .equal('Breakfast'); expect(res.body.todo) .to.have.property('description') .equal('Breakfast alone'); }); }); }); //api endpoints //import and define express framework import express from 'express'; import todoController from '../todoControllers/todo'; //create router handler const router = express.Router(); router.get('/api/v1/todos', todoController.getAllTodos); router.get('api/v1/todos/:id', todoController.getTodo); router.post('/api/v1/todos', todoController.createTodo); router.put('/api/v1/todos/:id', todoController.updateTodo); router.delete('/api/v1/todos/:id', todoController.deleteTodo); export default router; //controllers for api endpoints import db from '../db/db'; class todosController { getAllTodos(req, res) { return res.status(200).send({ success: 'true', message: 'todos retrieved successfully', todos: db }); } getTodo(req, res) { const id = parseInt(req.params.id, 10); db.map(todo => { if (todo.id === id) { return res.status(200).send({ success: 'true', message: 'todo retrieved successfully', todo }); } }); return res.status(400).send({ success: 'false', message: 'todo does not exist' }); } createTodo(req, res) { if (!req.body.title) { return res.status(400).send({ success: 'false', message: 'title is required' }); } else if (!req.body.description) { return res.status(400).send({ success: 'false', message: 'description is required' }); } const todo = { id: db.length + 1, title: req.body.title, description: req.body.description }; db.push(todo); return res.status(201).send({ success: 'true', message: 'todo added successfully', todo }); } updateTodo(req, res) { const id = parseInt(req.params.id, 10); let todoFound; let itemIndex; db.map((todo, index) => { if (todo.id === id) { todoFound = todo; itemIndex = index; } }); if (!todoFound) { return res.status(404).send({ success: 'true', message: 'todo not found' }); } if (!req.body.title) { return res.status(400).send({ success: 'false', message: 'title is required' }); } else if (!req.body.description) { return res.status(400).send({ success: 'false', message: 'description is required' }); } const editedTodo = { // @ts-ignore id: todoFound.id, // @ts-ignore title: req.body.title || todoFound.title, // @ts-ignore description: req.body.description || todoFound.description }; db.splice(itemIndex, 1, editedTodo); return res.status(200).send({ success: 'true', message: 'todo updated successfully', editedTodo }); } deleteTodo(req, res) { const id = parseInt(req.params.id, 10); let todoFound; let itemIndex; db.map((todo, index) => { if (todo.id === id) { todoFound = todo; itemIndex = index; } }); if (!todoFound) { return res.status(404).send({ success: 'true', message: 'todo not found' }); } db.splice(itemIndex, 1); return res.status(200).send({ success: 'true', message: 'todo deleted successfully' }); } } const todoController = new todosController(); export default todoController; //place-holder database in the form of datasctructures const todos = [ { id: 1, title: 'lunch', description: 'Go for lunch by 2pm' } ]; //Creating module from data structure and exposing it to be used by parts of the server export default todos; //tests written so far including the initial snippet import chai from 'chai'; import { app } from '../app'; import http from 'chai-http'; import db from '../db/db'; let expect = chai.expect; chai.use(http); describe('Test all todo endpoints at "/api/v1/todos and "/api/v1/todo/:id" with (GET, POST, GET/id, PUT)', () => { before(() => {}); after(() => {}); //GET all todos it('should get all todos at "/ap1/v1/todos" with GET', () => { return chai .request(app) .get('/api/v1/todos') .then(res => { expect(res).to.have.status(200); expect(res).to.be.json; expect(res.body).to.be.an('object'); expect(res.body) .to.have.property('success') .eql('true'); expect(res.body) .to.have.property('message') .eql('todos retrieved successfully'); expect(res.body.todos).to.be.an('array'); expect( res.body.todos[Math.floor(Math.random() * res.body.todos.length)] ).to.have.property('id' && 'title' && 'description'); }); }); //POST a todo it('should add a todo at "/api/v1/todos" with POST', () => { return chai .request(app) .post('/api/v1/todos') .send({ title: 'Dinner', description: 'Dinner with bae' }) .then(res => { expect(res).to.have.status(201); expect(res).to.be.json; expect(res.body).to.be.an('object'); expect(res.body) .to.have.property('success') .eql('true'); expect(res.body) .to.have.property('message') .equal('todo added successfully'); expect(res.body.todo).to.be.an('object'); expect(res.body.todo) .to.have.property('id') .equal(db.length); expect(res.body.todo) .to.have.property('title') .equal('Dinner'); expect(res.body.todo) .to.have.property('description') .equal('Dinner with bae'); }); }); //corrected test still giving an 'AssertionError' it('should get a single todo at "/api/v1/todos/:id" with GET/id', () => { return chai .request(app) .post('/api/v1/todos') .send({ title: 'Breakfast', description: 'Breakfast alone' }) .then(resPost => { expect(resPost).to.have.status(201); return chai .request(app) .get('/api/v1/todos/2') .then(res => { expect(res).to.have.status(200); expect(res).to.be.json; expect(res.body).to.be.an('object'); expect(res.body) .to.have.property('success') .eql('true'); expect(res.body) .to.have.property('message') .equal('todo retrieved successfully'); expect(res.body.todo).to.be.an('object'); expect(res.body.todo) .to.have.property('id') .equal(1); expect(res.body.todo) .to.have.property('title') .equal('Breakfast'); expect(res.body.todo) .to.have.property('description') .equal('Breakfast alone'); }); }); }); }); 

有人可以解釋為什么嗎? PS:我更新了問題,以顯示數據庫的api端點,測試和占位符,從本質上講,我需要有關如何處理涉及id的請求的提示。

您有兩個問題:

盡管遇到斷言錯誤,您的測試也不會失敗

這是因為在第14行中,您缺少return 由於您在第12行中注冊的函數不會返回任何內容,因此Promise會解決。 結果,您返回到第8行的承諾也將解決,並且您的測試也不會失敗,盡管應該這樣做。

由於您不返回被拒絕的承諾,因此不會傳播錯誤。 這就是為什么您收到錯誤消息的原因。

斷言錯誤本身

您正在創建資源,然后假設該資源的ID為2,然后請求該資源。您將收到404響應,這意味着該資源根本沒有被創建或具有不同的ID。

創建資源時,您需要以某種方式為其分配一個ID(看起來您只是為此使用了一個計數器,但是如果沒有看到您的實現,就無法確定)。 POST響應應提供有關此ID的一些信息。 理想情況下,它將id作為Location標頭發送,但通常將完整創建的資源作為響應正文發送。 因此,在發出GET請求之前,您需要從POST響應中提取ID。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM