简单的快速应用程序在运行时可以工作,但测试失败
使用express,我应该编写一个应用程序,从提供的JSON文件中获取曲目信息:
- 获取所有曲目
- 按id获取特定曲目
- 获取按曲目名称或持续时间排序的曲目列表(取决于sortBy查询字符串参数)
当我使用 Postman 摆弄该应用程序时,该应用程序运行良好,但当使用 Jest 和 Supertest 编写测试时,它们都失败了。
应用程序
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const logger = require('morgan');
const tracksRouter = require('./routes/routes-tracks');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use('/tracks', tracksRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.send(err.message);
});
module.exports = app;
路由
const express = require('express');
const router = express.Router();
const tracks = require('../controllers/controller');
router.get('/sorted', function (req, res) {
try {
const result = tracks.getSorted(req.query.sortBy);
res.status(200).send(result);
res.end();
} catch (error) {
res.status(500).send(error);
res.end();
}
});
router.get('/:id', function (req, res) {
try {
const result = tracks.getById(req.params.id);
res.status(200).send(result);
res.end();
} catch (error) {
res.status(500).send(error);
res.end();
}
});
router.get('/', function (req, res) {
try {
const result = tracks.getAll();
res.status(200).send(result);
res.end();
} catch (error) {
res.status(500).send(error);
res.end();
}
});
module.exports = router;
路由测试
const app = require('../../app');
const request = require('supertest');
describe('GET /tracks', () => {
it('GET /tracks/sorted?sortBy=duration should return array of tracks sorted by duration', () => {
const res = request(app).get('/tracks/sorted?sortBy=duration');
expect(res.statusCode).toEqual(200);
expect(res.body[0].id).toEqual(ID_EDITED);
});
it('GET /tracks/sorted?sortBy=name should return array of tracks sorted by name', () => {
const res = request(app).get('/tracks/sorted?sortBy=name');
expect(res.statusCode).toEqual(200);
expect(res.body[0].artist.name).toEqual(ARTIST_EDITED);
});
it('GET /tracks:id should return track with given id', () => {
const res = request(app).get('/tracks/ID_EDITED');
expect(res.statusCode).toEqual(200);
expect(res.body.id).toEqual(ID_EDITED);
expect(res.body.title).toEqual(SONGNAME_EDITED);
});
it('GET /tracks should return an array of all tracks', () => {
const res = request(app).get('/tracks');
expect(res.statusCode).toEqual(200);
expect(res.body[0]).toHaveProperty('duration');
});
});
控制器
const database = require('../tools/db-import');
const trackList = database.getTrackList();
function getAll() {
try {
return trackList;
} catch (error) {
return error;
}
}
function getById(trackId) {
try {
return trackList.find((item) => item.id == trackId);
} catch (error) {
return error;
}
}
function getSorted(sortParameter) {
try {
if (sortParameter == 'duration') {
return trackList.sort((a, b) => (a.duration > b.duration) ? 1 : -1);
} else if (sortParameter == 'name') {
return trackList.sort((a, b) => (a.artist.name > b.artist.name) ? 1 : -1);
}
else {
return 'Wrong input.'
}
} catch (error) {
return error;
}
}
module.exports.getAll = getAll;
module.exports.getById = getById;
module.exports.getSorted = getSorted;
模型
const tracks = require('../models/tracks');
function getAll() {
try {
return tracks.getAll();
} catch (error) {
return error;
}
}
function getById(id) {
try {
return tracks.getById(id);
} catch (error) {
return error;
}
}
function getSorted(sortParameter) {
try {
return tracks.getSorted(sortParameter);
} catch (error) {
return error;
}
}
module.exports.getAll = getAll;
module.exports.getById = getById;
module.exports.getSorted = getSorted;
数据库导入
const data = require('../database/JSON_EDITED.json');
function getTrackList() {
return data.tracks.data;
}
module.exports.getTrackList = getTrackList;
笑话的失败消息示例:
expect(received).toEqual(expected) // deep equality
Expected: 200
Received: undefined
8 | const res = request(app).get('/tracks/sorted?sortBy=duration');
9 |
> 10 | expect(res.statusCode).toEqual(200);
| ^
11 | expect(res.body[0].id).toEqual(ID_EDITED);
12 | });
13 |
at Object.<anonymous> (routes/__test__/routes-tracks.test.js:10:32)
Using express, I am supposed to write an app that gets track info from a JSON file that was provided:
- get all tracks
- get specific track by id
- get a list of tracks ordered by track name or duration (depends on the sortBy query string parameter)
The app works fine when I fiddle with it using Postman, but when writing tests using Jest and Supertest they all fail.
app
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const logger = require('morgan');
const tracksRouter = require('./routes/routes-tracks');
const app = express();
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use('/tracks', tracksRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.send(err.message);
});
module.exports = app;
routes
const express = require('express');
const router = express.Router();
const tracks = require('../controllers/controller');
router.get('/sorted', function (req, res) {
try {
const result = tracks.getSorted(req.query.sortBy);
res.status(200).send(result);
res.end();
} catch (error) {
res.status(500).send(error);
res.end();
}
});
router.get('/:id', function (req, res) {
try {
const result = tracks.getById(req.params.id);
res.status(200).send(result);
res.end();
} catch (error) {
res.status(500).send(error);
res.end();
}
});
router.get('/', function (req, res) {
try {
const result = tracks.getAll();
res.status(200).send(result);
res.end();
} catch (error) {
res.status(500).send(error);
res.end();
}
});
module.exports = router;
routes test
const app = require('../../app');
const request = require('supertest');
describe('GET /tracks', () => {
it('GET /tracks/sorted?sortBy=duration should return array of tracks sorted by duration', () => {
const res = request(app).get('/tracks/sorted?sortBy=duration');
expect(res.statusCode).toEqual(200);
expect(res.body[0].id).toEqual(ID_EDITED);
});
it('GET /tracks/sorted?sortBy=name should return array of tracks sorted by name', () => {
const res = request(app).get('/tracks/sorted?sortBy=name');
expect(res.statusCode).toEqual(200);
expect(res.body[0].artist.name).toEqual(ARTIST_EDITED);
});
it('GET /tracks:id should return track with given id', () => {
const res = request(app).get('/tracks/ID_EDITED');
expect(res.statusCode).toEqual(200);
expect(res.body.id).toEqual(ID_EDITED);
expect(res.body.title).toEqual(SONGNAME_EDITED);
});
it('GET /tracks should return an array of all tracks', () => {
const res = request(app).get('/tracks');
expect(res.statusCode).toEqual(200);
expect(res.body[0]).toHaveProperty('duration');
});
});
controller
const database = require('../tools/db-import');
const trackList = database.getTrackList();
function getAll() {
try {
return trackList;
} catch (error) {
return error;
}
}
function getById(trackId) {
try {
return trackList.find((item) => item.id == trackId);
} catch (error) {
return error;
}
}
function getSorted(sortParameter) {
try {
if (sortParameter == 'duration') {
return trackList.sort((a, b) => (a.duration > b.duration) ? 1 : -1);
} else if (sortParameter == 'name') {
return trackList.sort((a, b) => (a.artist.name > b.artist.name) ? 1 : -1);
}
else {
return 'Wrong input.'
}
} catch (error) {
return error;
}
}
module.exports.getAll = getAll;
module.exports.getById = getById;
module.exports.getSorted = getSorted;
model
const tracks = require('../models/tracks');
function getAll() {
try {
return tracks.getAll();
} catch (error) {
return error;
}
}
function getById(id) {
try {
return tracks.getById(id);
} catch (error) {
return error;
}
}
function getSorted(sortParameter) {
try {
return tracks.getSorted(sortParameter);
} catch (error) {
return error;
}
}
module.exports.getAll = getAll;
module.exports.getById = getById;
module.exports.getSorted = getSorted;
database import
const data = require('../database/JSON_EDITED.json');
function getTrackList() {
return data.tracks.data;
}
module.exports.getTrackList = getTrackList;
example of jest's failure message:
expect(received).toEqual(expected) // deep equality
Expected: 200
Received: undefined
8 | const res = request(app).get('/tracks/sorted?sortBy=duration');
9 |
> 10 | expect(res.statusCode).toEqual(200);
| ^
11 | expect(res.body[0].id).toEqual(ID_EDITED);
12 | });
13 |
at Object.<anonymous> (routes/__test__/routes-tracks.test.js:10:32)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您查看超级测试文档,您可以看到
请求
函数是异步的并返回一个承诺。它们提供不同的语法,但我个人会使用
async/await
语法:但您也可以使用
then
回调:最后,您可以使用 Jest 的异步匹配器(并不理想)对于此用例,此处仅进行部分检查):
If you take a look at the supertest documentation, you can see that the
request
function is asynchronous and returns a promise.They provide different syntax but I would personally used the
async/await
one:But you could also use a
then
callback:And finally, you could use Jest's async matchers (not ideal for this use case, only partial check is done here):