如何正确模拟套接字连接以模拟各种 on.('data' 事件

How to mock a socket connection properly to simulate various on.('data' events

我正在测试一种方法,该方法 returns 基于从套接字过滤的数据的 Promise:

async readData(sConn) {
    if(!sConn) {
        throw new Error('READ_SOCK_ERROR');
    }

    let rawData;

    return new Promise((resolve, reject) => {
        sConn.on('data', async (data) => {
            try {
                rawData = data.toString();
                return resolve(rawData);
            } catch (error) {
                return reject(new Error(`Error reading response. Details: ${error.stack}`));
            }
        }
    }
}

如何正确模拟套接字连接,以便模拟在数据事件中发送的各种数据? 这就是我正在使用的,但测试挂起并最终超时....

it('It should not throw error and return simulated data string', async function () {
        let result;
        let error = false;
        let mockedData = 'This is\na simultated response\nfrom the socket';
        
        const sConn = {
            on: () => Promise.resolve(mockedData),
        };

        try {
            result = await rewiredFileContainingMethodToTest.readData(sConn);
            console.log(result);
        } catch (err) {
            error = err;
            console.log('Error caught: '+err);
        }
        expect(error).to.be.false;
        sinon.assert.callCount(sConn.on, 1);
        expect(result).contains(mockedData);
    });

您可以使用 stub.callsFake(fakeFunction),它使存根在调用时调用所提供的 fakeFunction

例如

file.js:

const file = {
  async readData(sConn) {
    if (!sConn) {
      throw new Error('READ_SOCK_ERROR');
    }

    let rawData;

    return new Promise((resolve, reject) => {
      sConn.on('data', async (data) => {
        try {
          rawData = data.toString();
          return resolve(rawData);
        } catch (error) {
          return reject(new Error(`Error reading response. Details: ${error.stack}`));
        }
      });
    });
  },
};

export { file };

file.test.js:

import { expect } from 'chai';
import sinon from 'sinon';
import { file } from './file';

describe('65594632', () => {
  it('It should not throw error and return simulated data string', async function () {
    let mockedData = 'This is\na simultated response\nfrom the socket';

    const sConn = {
      on: sinon.stub().callsFake(async (event, callback) => {
        await callback(mockedData);
      }),
    };

    const result = await file.readData(sConn);
    sinon.assert.callCount(sConn.on, 1);
    expect(result).to.be.equal(mockedData);
  });
});

单元测试结果:

  65594632
    ✓ It should not throw error and return simulated data string


  1 passing (7ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   81.82 |       50 |     100 |      80 |                   
 file.ts  |   81.82 |       50 |     100 |      80 | 4,15              
----------|---------|----------|---------|---------|-------------------