我正在使用Nodejs创建一个API,并试图对其进行测试,但是当我运行npm run test时,发生了以下错误,并且我不知道如何解决该问题,因此我尝试放置done()在每次测试的最后,但没有成功,我还尝试将超时设置为10000ms,但相同的错误不断发生。
我正在使用docker将mongodb和后端联机。
错误:超时超过2000毫秒。对于异步测试和挂钩,请确保调用了“ done()”;如果返回承诺,请确保其解决。 (/home/nodejs/app/tests/unitTests.js)
tests / unitTests.js
const test = require('tape')
const request = require('supertest')
const express = require('express')
const User = require('../models/User')
const app = require('../index')
let userId
before(done => {
app.on('APP_STARTED', () => {
done()
})
})
describe('API Integration Test', () => {
it('Runs all tests', done => {
test('/api/v1/users/', assert => {
request(app)
.post('/api/v1/users/')
.send(new User('test name', '27810384074'))
.expect(200)
.end((err, res) => {
if (err) return assert.fail(JSON.stringify(res))
assert.pass('Created a new user successfully, test passed!')
assert.end()
done()
})
})
test('/api/v1/users/', assert => {
request(app)
.get('/api/v1/users/')
.expect(200)
.end((err, res) => {
if (err) return assert.fail(JSON.stringify(res))
userId = res.body[0]._id
assert.pass('Got all users successfully, test passed!')
assert.end()
done()
})
})
test('/api/v1/users/:id', assert => {
request(app)
.get(`/api/v1/users/${userId}`)
.expect(200)
.end((err, res) => {
if (err) return assert.fail(JSON.stringify(res))
assert.pass('Got a specific user successfully, test passed!')
assert.end()
done()
})
})
test('/api/v1/users/:id', assert => {
request(app)
.patch(`/api/v1/users/${userId}`)
.send(new User('test name edit', 'test cpfcnpj edit'))
.expect(200)
.end((err, res) => {
if (err) return assert.fail(JSON.stringify(res))
assert.pass('Edited a users successfully, test passed!')
assert.end()
done()
})
})
test('/api/v1/users/:id', assert => {
request(app)
.delete(`/api/v1/users/${userId}`)
.expect(200)
.end((err, res) => {
if (err) return assert.fail(JSON.stringify(res))
assert.pass('Deleted a specific user successfully, test passed!')
assert.end()
done()
})
})
})
})
index.js
const express = require('express')
const bodyParser = require('body-parser')
const MongoClient = require('mongodb')
const dbName = process.env.NODE_ENV === 'dev' ? 'database-test' : 'database'
const url = `mongodb://${process.env.MONGO_INITDB_ROOT_USERNAME}:${process.env.MONGO_INITDB_ROOT_PASSWORD}@${dbName}:27017?authMechanism=SCRAM-SHA-1&authSource=admin`
const options = {
useNewUrlParser: true,
reconnectTries: 60,
reconnectInterval: 1000
}
const routes = require('./routes/userRoutes.js')
const port = process.env.PORT || 80
const app = express()
const http = require('http').Server(app)
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true}))
app.use('/api/v1', routes)
app.use((req, res) => {
res.status(404)
})
MongoClient.connect(url, options, (err, database) => {
if(err) {
console.log(`FATAL MONGODB CONNECTION ERROR: $(err):$(err.stack)`)
process.exit(1)
}
app.locals.db = database.db('api')
http.listen(port, () => {
console.log("Listening on port " + port)
app.emit('APP_STARTED')
})
})
module.exports = app
package.json
{
"name": "user-register",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "docker-compose -f docker/docker-compose.test.yml up --build --abort-on-container-exit",
"production": "docker-compose -f docker/docker-compose.yml up -d",
"build": "docker-compose -f docker/docker-compose.yml build"
},
"keywords": [
"express",
"mongo"
],
"author": "",
"license": "ISC",
"dependencies": {
"body-parser": "^1.18.3",
"express": "^4.16.4",
"mongodb": "^3.1.10"
},
"devDependencies": {
"mocha": "^5.2.0",
"supertest": "^3.3.0",
"tape": "^4.9.1"
}
}
模型/User.js
module.exports = class User {
constructor(name, cpfcnpj){
this.name = name
this.cpfcnpj = cpfcnpj
}
}
routes / userRoutes.js
const express = require('express')
const User = require('../models/User')
const router = express.Router()
router.get('/users/', (req, res, next) => {
req.app.locals.db.collection('users').find({}).toArray((err, result) => {
if (err) {
res.status(400).send({
'error': err
})
}
if (result === undefined || result.length === 0) {
res.status(400).send({
'error': 'No users in database'
})
} else {
res.status(200).send(result)
}
})
})
router.get('/users/:id', (req, res, next) => {
req.app.locals.db.collection('users').findOne({
'_id': req.params.id
}, (err, result) => {
if (err) {
res.status(400).send({
'error': err
})
}
if (result === undefined) {
res.status(400).send({
'error': 'No user matching that id was found'
})
} else {
res.status(200).send(result)
}
})
})
router.post('/users/', (req, res, next) => {
const newUser = new User(req.body.title, req.body.username, req.body.body)
req.app.locals.db.collection('users').insertOne({
newUser
}, (err, result) => {
if (err) {
res.status(400).send({
'error': err
})
}
res.status(200).send(result)
})
})
router.delete('/users/:id', (req, res, next) => {
req.app.locals.db.collection('users').deleteOne({
'_id': req.params.id
}, (err, result) => {
if (err) {
res.status(400).send({
'error': err
})
}
res.status(200).send(result)
})
})
router.patch('/users/:id', (req, res, next) => {
req.app.locals.db.collection('users').updateOne({
'_id': req.params.id
}, {
$set: {
title: req.body.title,
username: req.body.username,
body: req.body.body
}
}, (err, result) => {
if (err) {
res.status(400).send({
'error': err
})
}
res.status(200).send(result)
})
})
module.exports = router
Dockerfiles:
Dockerfile.test
FROM docker_backend
ADD https://github.com/ufoscout/docker-compose-wait/releases/download/2.2.1/wait /wait
RUN chmod +x /wait
ENV NODE_ENV dev
RUN npm install && npm install -g mocha --timeout 10000
ARG port=80
CMD /wait && mocha tests/unitTests.js --exit
docker-compose.test.yml
version: '3'
services:
backend-test:
build:
context: ../
dockerfile: docker/Dockerfile.test
args:
port: ${PORT}
env_file:
- ../.env
environment:
WAIT_HOSTS: database-test:27017
database-test:
image: mongo:4.0
env_file:
- ../.env
volumes:
- ".${MONGO_TEST_DATA_DIR}:${MONGO_TEST_DATA_DIR}"
expose:
- 27017
command: "mongod --smallfiles --logpath=${MONGO_LOG_FILE}"
错误:
database-test_1 | MongoDB init process complete; ready for start up.
database-test_1 |
backend-test_1 | Host database-test:27017 not yet available
backend-test_1 | Host database-test:27017 not yet available
backend-test_1 | Host database-test:27017 is now available
backend-test_1 |
backend-test_1 |
backend-test_1 | Listening on port 80
backend-test_1 | API Integration Test
backend-test_1 | TAP version 13
backend-test_1 | # /api/users/new
backend-test_1 | 1) Runs all tests
backend-test_1 |
backend-test_1 |
backend-test_1 | 0 passing (2s)
backend-test_1 | 1 failing
backend-test_1 |
backend-test_1 | 1) API Integration Test
backend-test_1 | Runs all tests:
backend-test_1 | Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves. (/home/nodejs/app/tests/unitTests.js)