Express + Mocha + Chai 错误:服务器没有监听

问题描述

我正在编写一个简单的 TypeScript Express 应用程序,它可以获取有关 YouTube 视频的信息。这是路由器(安装到 /api):

import express from 'express';
import ytdl    from 'ytdl-core';
import bodyParser from 'body-parser';

const router = express.Router();

router.post('/info',bodyParser.json(),async (req,res,next) => {
    const videoID = req.body.videoID

    if (!ytdl.validateID(videoID)) {
        const error = new Error('Invalid video ID')
        res.status(400).json({error: error.toString()}).send;
        next();
    } else {
        const videoFormats = await (await ytdl.getInfo(videoID)).formats;
        res.setHeader('Content-type','application/json');
        res.send(videoFormats);
    } 
});

export default router;

今天我尝试用 Mocha + Chai 编写我的第一个测试。 api/info 端点需要 POST,从正文中获取 videoID 并使用 JSON 进行响应。到目前为止,这是我对端点的测试。

import app from '../index'  
import chaiHttp from 'chai-http'
import chai from 'chai'

chai.use(chaiHttp);

const expect = chai.expect;
const get    = chai.request(app).get;
const post   = chai.request(app).post;

describe('API',() => {
    describe('POST /api/info',() => {
        it('given videoID of a publically available video,responds with 200 OK and JSON that contains an array of objects',async () => {
            const res = await post('/api/info')
                                .send({"videoID": "OrxmtDw4pVI"});

            expect(res).to.have.status(200);
            expect(res.body).to.be.an('array');            
        }).timeout(5000);

        it('given an invalid videoID,responds with 400 and an Error',async () => {
            const res = await post('/api/info')
                                .send({"videoID": "qwerty"});

            expect(res).to.have.status(400);
        });
    });
});

测试结果如下:

API
    POST /api/info
      √ given videoID of a publically available video,responds with 200 OK and JSON that contains an array of objects (1028ms)
      1) given an invalid videoID,responds with 400 and an Error


  1 passing (1s)
  1 failing

  1) API
       POST /api/info
         given an invalid videoID,responds with 400 and an Error:
     Error: Server is not listening
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! ytb--down@1.0.0 test: `mocha -r ts-node/register src/**/*.spec.ts --exit`
npm ERR! Exit status 1

如您所见,第二个测试由于 Server is not listening 错误而失败。如果我skip第一次测试,它不会发生

我使用 Postman 用这些数据手动测试了这个端点,没有发现会导致服务器崩溃的问题,也没有抛出错误

我使用 npm run test 命令启动测试,这是来自 package.json 的脚本:

"scripts": {
    "test": "mocha -r ts-node/register src/**/*.spec.ts --exit"

我怀疑测试套件本身有问题,但我无法确定解决方案。我在这里错过了什么?

解决方法

我想我找到了。

似乎我的测试确实包含了一个错误,对于像我这样的初学者来说并不明显。

不想像这样获得 getpost 快捷方式:

const get    = chai.request(app).get;
const post   = chai.request(app).post;

我认为真正的错误是我在这里调用了 request()。相反,应该只是抓住 chai.request 的快捷方式:

const request = chai.request;

测试现在工作正常。测试文件现在如下所示。

import server from '../index'  
import chaiHttp from 'chai-http'
import chai from 'chai'

chai.use(chaiHttp);
const expect  = chai.expect;
const request = chai.request;

describe('API',() => {
    
    describe('POST /api/info',() => {
        it('given videoID of a publically available video,responds with 200 and JSON that contains an array of objects',async () => {
            const res = await request(server)
                                .post('/api/info')
                                .send({"videoID": "OrxmtDw4pVI"});

            expect(res).to.have.status(200);
            expect(res.body).to.be.an('array');            
        });

        it('given an invalid videoID,responds with 400 and an Error',async () => {
            const res = await request(server)
                                .post('/api/info')
                                .send({"videoID": "qwerty"});

            expect(res).to.have.status(400);
            expect(res.body.error).to.include('Error');
        });
    });
});

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...