繁体   English   中英

如何修复:在 Jest 中运行测试时“TypeError:wsModule.Server 不是构造函数”

[英]How do I fix: “TypeError: wsModule.Server is not a constructor” when running tests in Jest

我是 Jest 的新手,我想开始为 Node.js 服务器编写一些集成测试。 当我尝试运行测试时,我收到"TypeError: wsModule.Server is not a constructor"错误。 为什么我的测试环境不会初始化套接字服务器?

server.js:

const app = require('express')();
const server = require('http').Server(app);
const io = require('socket.io')(server); <-- TEST FAILS BECAUSE OF SOCKET MODULE
const router = require('./router/router');
const bodyParser = require('body-parser');
const cors = require('cors');
require('./socket/socket')(io); 

// Allow CORS so our client can consume JSON
app.use(cors())

// Takes the raw requests and turns them into usable properties on req.body
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

// Use our router
app.use('/', router);

server.listen(3000, (req, res) => {
  console.log("listen at 3000!");
});

module.exports = app;

socket.js:

const userService = require('../services/userService');
const roomService = require('../services/roomService');

module.exports = function (io) {

  io.on("connection", socket => {

    console.log('there has been a connection with: ' + socket.id);

    socket.on('set-username', ({ roomId, username }) => {
      userService.setUsername(roomId, username, socket, io);
    });

    socket.on('start-game', ({ roomId, hostName }) => {
      roomService.startGame(roomId, hostName, socket, io);
    });

});

roomService.test.js:

const chai = require('chai');
const chaiHttp = require('chai-http');
const server = require('../../server');
const { expect } = chai;
chai.use(chaiHttp);

describe("example", () => {
  test('should run', () => {
    expect(true).to.be.true;
  })
})

测试失败,因为server.listen异步的,而您的测试是同步

为什么我的测试环境不会初始化套接字服务器?

问题是您的测试将在 HTTP 服务器启动并且 Socket.IO 服务器连接到它之前完成。

请参阅测试异步代码

您可以在server.js中注释server.listen并导出server ,以便在测试时使用它,并告诉jest等到服务器启动,然后运行测试的 rest。

服务器.js

- server.listen(3000, (req, res) => { console.log("listen at 3000!"); });
- module.exports = app;

+ module.exports = server

roomService.test.js

const server = require('../../server');

describe("example", () => {
    beforeAll(done => { //pass a callback to tell jest it is async
        //start the server before any test
        server.listen(3000, () => done());
    })

    afterAll(done => { //pass a callback to tell jest it is async
        //close the server after all tests
        server.listening ? server.close(() => done()) : done();
    })

    test('should run', () => {
        expect(true).to.be.true;
    })
})

当然,当您想在开发模式下再次运行您的应用程序时,您必须取消注释它。

为避免在此文件中注释/取消注释,请创建一个单独的模块,您可以在其中启动服务器并使其成为应用程序入口点。

这是您的文件的外观

服务器.js

const app = require('./app');
const server = require('http').Server(app);
const io = require('socket.io')(server);
require('./socket/socket')(io); 
module.exports = server;

开始.js:

const server = require('./server');
server.listen(3000, (req, res) => {
    console.log("listen at 3000!");
});

应用程序.js

const app = require('express')();
const router = require('./router/router');
const bodyParser = require('body-parser');
const cors = require('cors');

app.use(cors())
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use('/', router);

module.exports = app;

使用start.js作为应用程序入口点,您现在可以运行应用程序和测试,而无需进行任何更改

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM