Reputation: 170
I'm writing a simple TypeScript Express app that would get info about YouTube videos. Here is the router (mounted to /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;
Today I've attempted to write my first tests with Mocha + Chai. The api/info
endpoint expects POST, grabs videoID
from the body and responds with JSON. Here are my tests for the endpoint so far.
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);
});
});
});
The test results are as follows:
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! [email protected] test: `mocha -r ts-node/register src/**/*.spec.ts --exit`
npm ERR! Exit status 1
As you can see, the second test fails due to the Server is not listening
error. It doesn't happen if I skip
the first test.
I used Postman to test this endpoint with this data manually and found no issues that would cause server crashes, no errors are thrown.
I launch tests with the npm run test
command, here is the script from package.json
:
"scripts": {
"test": "mocha -r ts-node/register src/**/*.spec.ts --exit"
I suspect there is something wrong with the test suite itself, but I am unable to pinpoint a solution. What am I missing here?
Upvotes: 1
Views: 910
Reputation: 170
I think I found it.
Seems like my tests did contain a mistake and not an obvious one for a beginner like myself.
You don't want to get get
and post
shortcuts like so:
const get = chai.request(app).get;
const post = chai.request(app).post;
I think the actual mistake is that I invoked request()
here. Instead, should've just grabbed a shortcut for chai.request
:
const request = chai.request;
Tests work fine now. Test file now looks as follows.
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');
});
});
});
Upvotes: 2