代码之家  ›  专栏  ›  技术社区  ›  James Barrett

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

  •  0
  • James Barrett  · 技术社区  · 6 年前

    我是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;
      })
    })
    
    0 回复  |  直到 6 年前
        1
  •  7
  •   mousto090    6 年前

    测试失败的原因是 server.listen 异步 你的测试是 同步

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

    问题是,您的测试将在HTTP服务器启动之前完成 插座。IO服务器已连接到它。

    看见 Testing Asynchronous Code

    您可以发表评论 服务器.listen 在里面 server.js 并出口 server 所以你可以使用 在测试和告知时 jest 等待服务器启动,然后运行其余的测试。

    server.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;
        })
    })
    

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

    为了避免在此文件中添加注释/取消注释,请在启动服务器和 让它成为应用程序的入口点。

    以下是您的文件的外观

    server.js

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

    start.js:

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

    app.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 在应用程序入口点,您现在可以运行应用程序和测试,而无需进行任何更改

    推荐文章