用 Jest 模拟继承的类

can*_*ton 5 sockets unit-testing mocking node.js jestjs

我正在扩展net.Socket。这样做时,我将按如下方式覆盖连接方法。

class ENIP extends Socket {
    constructor() {
        super();

        this.state = {
            session: { id: null, establishing: false, established: false },
            error: { code: null, msg: null }
        };
    }

    connect(IP_ADDR) {
        const { registerSession } = encapsulation; //returns a buffer to send

        this.state.session.establishing = true;

        return new Promise(resolve => {
            super.connect(EIP_PORT, IP_ADDR, () => { // This is what i want to mock -> super.connect
                this.state.session.establishing = false;

                this.write(registerSession());
                resolve();
            });
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我想模拟底层的Socket类,以便我可以模拟super.connect. 查看了 Facebook关于此事的文档后,我不确定如何继续为此类开发测试,因为所有方法都将扩展super.someMethodToMock. 有谁知道我应该采取的方法?如果我可以提供任何澄清细节,请告诉我。

sli*_*wp2 4

您可以使用jest.spyOn(object, methodName)创建模拟方法Socket.prototype。

\n

例如

\n

index.js:

\n
import { Socket } from \'net\';\n\nconst EIP_PORT = 3000;\nconst encapsulation = {\n  registerSession() {\n    return \'session\';\n  },\n};\n\nexport class ENIP extends Socket {\n  constructor() {\n    super();\n    this.state = {\n      session: { id: null, establishing: false, established: false },\n      error: { code: null, msg: null },\n    };\n  }\n\n  connect(IP_ADDR) {\n    const { registerSession } = encapsulation;\n    this.state.session.establishing = true;\n\n    return new Promise((resolve) => {\n      super.connect(EIP_PORT, IP_ADDR, () => {\n        this.state.session.establishing = false;\n        this.write(registerSession());\n        resolve();\n      });\n    });\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

index.test.js:

\n
import { ENIP } from \'./\';\nimport { Socket } from \'net\';\n\ndescribe(\'ENIP\', () => {\n  afterAll(() => {\n    jest.restoreAllMocks();\n  });\n  describe(\'#connect\', () => {\n    it(\'should pass\', async () => {\n      const writeSpy = jest.spyOn(Socket.prototype, \'write\').mockImplementation();\n      const connectSpy = jest.spyOn(Socket.prototype, \'connect\').mockImplementationOnce((port, addr, callback) => {\n        callback();\n      });\n      const enip = new ENIP();\n      await enip.connect(\'localhost\');\n      expect(writeSpy).toBeCalledWith(\'session\');\n      expect(connectSpy).toBeCalledWith(3000, \'localhost\', expect.any(Function));\n    });\n  });\n});\n
Run Code Online (Sandbox Code Playgroud)\n

带有覆盖率报告的单元测试结果:

\n
 PASS  src/stackoverflow/48888509/index.test.jsx (10.43s)\n  ENIP\n    #connect\n      \xe2\x9c\x93 should pass (7ms)\n\n-----------|----------|----------|----------|----------|-------------------|\nFile       |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |\n-----------|----------|----------|----------|----------|-------------------|\nAll files  |      100 |      100 |      100 |      100 |                   |\n index.jsx |      100 |      100 |      100 |      100 |                   |\n-----------|----------|----------|----------|----------|-------------------|\nTest Suites: 1 passed, 1 total\nTests:       1 passed, 1 total\nSnapshots:   0 total\nTime:        12.357s\n
Run Code Online (Sandbox Code Playgroud)\n

源代码: https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/48888509

\n