使用 Jest、Supertest、MongoDB 和 Express 进行测试时的拆卸错误
Teardown Errors when testing with Jest, Supertest, MongoDB, and Express
我正在使用 Jest 和 Supertest 测试我的 Express 路线。在设置应用程序时,我还连接到 MongoDB 并将 MongoClient 添加到 app.locals
。
我收到一个错误,当我注释掉对 MongoClient 的调用时不会发生该错误。
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.
at BufferList.Readable (server/node_modules/readable-stream/lib/_stream_readable.js:179:22)
at BufferList.Duplex (server/node_modules/readable-stream/lib/_stream_duplex.js:67:12)
at new BufferList (server/node_modules/bl/bl.js:33:16)
at new MessageStream (server/node_modules/mongodb/lib/cmap/message_stream.js:35:21)
at new Connection (server/node_modules/mongodb/lib/cmap/connection.js:54:28)
/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:111
var isDuplex = stream instanceof Duplex;
^
TypeError: Right-hand side of 'instanceof' is not callable
at new ReadableState (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:111:25)
at BufferList.Readable (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:183:25)
at BufferList.Duplex (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_duplex.js:67:12)
at new BufferList (/Users/zackchan/Documents/dev/server/node_modules/bl/bl.js:33:16)
at new MessageStream (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/cmap/message_stream.js:35:21)
at new Connection (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/cmap/connection.js:54:28)
at /Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:36:29
at callback (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:280:5)
at TLSSocket.connectHandler (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:325:5)
at Object.onceWrapper (events.js:421:28)
当我注释掉我的 MongoClient 调用时,我收到了这个 Jest 警告:
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
这是我的测试脚本和应用程序模块
app.js
const https = require('https');
const fs = require('fs');
const path = require('path');
const dotenv = require('dotenv');
const express = require('express');
const rateLimiter = require('express-rate-limit');
const { MongoClient } = require('mongodb');
const app = express();
const port = process.env.PORT || 443;
const limit = rateLimiter({ window: 15 * 60 * 1000, max: 100 });
var httpsOptions;
if(process.env.NODE_ENV === 'development'){
const rootCA = require('ssl-root-cas').create().addFile(path.join(__dirname, './cert/CA.pem'));
https.globalAgent.options.ca = rootCA;
httpsOptions = {
key: fs.readFileSync(path.join(__dirname, './cert/localhost.key')),
cert: fs.readFileSync(path.join(__dirname, './cert/localhost.crt'))
};
}
MongoClient.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true }, (err, mongoClient) => {
if(err) throw err;
app.locals.mongoClient = mongoClient;
});
app.use(limit);
app.use(express.json());
app.get('/', (req, res) => {
res.json({path: '/'});
});
const server = https.createServer(httpsOptions, app).listen(port);
module.exports = app;
test.js
const dotenv = require('dotenv');
const path = require('path');
process.env = dotenv.config({path: path.resolve(__dirname, '.env')}).parsed;
const request = require('supertest');
const app = require('../app');
describe('GET /', () => {
it('responds with path of /', (done) => {
// app.locals is empty here
request(app).get('/').expect(JSON.stringify({path: '/'}), done);
});
});
我尝试在使用 app.locals.mongoClient.close()
的测试用例后关闭与 MongoDB 的连接,但此处未定义 mongoClient
。我也试过将 MongoClient.connect()
调用包装在异步函数中然后调用它,但这也无济于事。
有人对我应该尝试什么有想法吗?
我通过以下方式解决了这个问题:
- 按照 Jest docs 的说明进行操作。如果您将 MongoDB 连接分配给
test.js
文件中的 app.locals
,您仍然可以通过 req.app.locals
访问它。
- 在
app.js
中结束了我的 MongoClient.connect()
通话:
if(process.env.NODE_ENV === 'production'){
MongoClient.connect(...)
}
我正在使用 Jest 和 Supertest 测试我的 Express 路线。在设置应用程序时,我还连接到 MongoDB 并将 MongoClient 添加到 app.locals
。
我收到一个错误,当我注释掉对 MongoClient 的调用时不会发生该错误。
ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.
at BufferList.Readable (server/node_modules/readable-stream/lib/_stream_readable.js:179:22)
at BufferList.Duplex (server/node_modules/readable-stream/lib/_stream_duplex.js:67:12)
at new BufferList (server/node_modules/bl/bl.js:33:16)
at new MessageStream (server/node_modules/mongodb/lib/cmap/message_stream.js:35:21)
at new Connection (server/node_modules/mongodb/lib/cmap/connection.js:54:28)
/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:111
var isDuplex = stream instanceof Duplex;
^
TypeError: Right-hand side of 'instanceof' is not callable
at new ReadableState (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:111:25)
at BufferList.Readable (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_readable.js:183:25)
at BufferList.Duplex (/Users/zackchan/Documents/dev/server/node_modules/readable-stream/lib/_stream_duplex.js:67:12)
at new BufferList (/Users/zackchan/Documents/dev/server/node_modules/bl/bl.js:33:16)
at new MessageStream (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/cmap/message_stream.js:35:21)
at new Connection (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/cmap/connection.js:54:28)
at /Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:36:29
at callback (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:280:5)
at TLSSocket.connectHandler (/Users/zackchan/Documents/dev/server/node_modules/mongodb/lib/core/connection/connect.js:325:5)
at Object.onceWrapper (events.js:421:28)
当我注释掉我的 MongoClient 调用时,我收到了这个 Jest 警告:
Jest did not exit one second after the test run has completed.
This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.
这是我的测试脚本和应用程序模块
app.js
const https = require('https');
const fs = require('fs');
const path = require('path');
const dotenv = require('dotenv');
const express = require('express');
const rateLimiter = require('express-rate-limit');
const { MongoClient } = require('mongodb');
const app = express();
const port = process.env.PORT || 443;
const limit = rateLimiter({ window: 15 * 60 * 1000, max: 100 });
var httpsOptions;
if(process.env.NODE_ENV === 'development'){
const rootCA = require('ssl-root-cas').create().addFile(path.join(__dirname, './cert/CA.pem'));
https.globalAgent.options.ca = rootCA;
httpsOptions = {
key: fs.readFileSync(path.join(__dirname, './cert/localhost.key')),
cert: fs.readFileSync(path.join(__dirname, './cert/localhost.crt'))
};
}
MongoClient.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true }, (err, mongoClient) => {
if(err) throw err;
app.locals.mongoClient = mongoClient;
});
app.use(limit);
app.use(express.json());
app.get('/', (req, res) => {
res.json({path: '/'});
});
const server = https.createServer(httpsOptions, app).listen(port);
module.exports = app;
test.js
const dotenv = require('dotenv');
const path = require('path');
process.env = dotenv.config({path: path.resolve(__dirname, '.env')}).parsed;
const request = require('supertest');
const app = require('../app');
describe('GET /', () => {
it('responds with path of /', (done) => {
// app.locals is empty here
request(app).get('/').expect(JSON.stringify({path: '/'}), done);
});
});
我尝试在使用 app.locals.mongoClient.close()
的测试用例后关闭与 MongoDB 的连接,但此处未定义 mongoClient
。我也试过将 MongoClient.connect()
调用包装在异步函数中然后调用它,但这也无济于事。
有人对我应该尝试什么有想法吗?
我通过以下方式解决了这个问题:
- 按照 Jest docs 的说明进行操作。如果您将 MongoDB 连接分配给
test.js
文件中的app.locals
,您仍然可以通过req.app.locals
访问它。 - 在
app.js
中结束了我的MongoClient.connect()
通话:
if(process.env.NODE_ENV === 'production'){
MongoClient.connect(...)
}