最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jest test emitting events for eventemitter objects (express) - Stack Overflow

programmeradmin2浏览0评论

trying to get an inspiration from jest test emitting events for eventemitter objects (http) didn't solve my pain with express.

assume the following nodejs code

// server.js

const express = require("express");
const app = express();

const server = app.listen(8080,'127.0.0.1')
  .on("error", err => {
    // ...
  });

module.exports = server;

how to write a test using jest to emit the http "error" event (to cover the error event handler)?

i tried:

// server.test.js

it("should handle error", () => {
  jest.mock("express", () => () => ({
    listen: jest.fn().mockReturnThis(),
    on: jest.fn().mockImplementationOnce((event, handler) => {
      handler(new Error("network"));
    })
  }))
  const express = require("express");
  const app = express();
  const appListenSpy = jest.spyOn(app, "listen")
  require("./server");
  expect(appListenSpy).toBeCalledTimes(1);
  expect(app.listen).toBeCalledWith(8080,'127.0.0.1');
  expect(app.on).toBeCalledWith("error", expect.any(Function));
});

but what i get when running the test

 ● server › should handle listen error

    expect(jest.fn()).toBeCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

    > 29 |     expect(appListenSpy).toBeCalledTimes(1);

trying to get an inspiration from jest test emitting events for eventemitter objects (http) didn't solve my pain with express.

assume the following nodejs code

// server.js

const express = require("express");
const app = express();

const server = app.listen(8080,'127.0.0.1')
  .on("error", err => {
    // ...
  });

module.exports = server;

how to write a test using jest to emit the http "error" event (to cover the error event handler)?

i tried:

// server.test.js

it("should handle error", () => {
  jest.mock("express", () => () => ({
    listen: jest.fn().mockReturnThis(),
    on: jest.fn().mockImplementationOnce((event, handler) => {
      handler(new Error("network"));
    })
  }))
  const express = require("express");
  const app = express();
  const appListenSpy = jest.spyOn(app, "listen")
  require("./server");
  expect(appListenSpy).toBeCalledTimes(1);
  expect(app.listen).toBeCalledWith(8080,'127.0.0.1');
  expect(app.on).toBeCalledWith("error", expect.any(Function));
});

but what i get when running the test

 ● server › should handle listen error

    expect(jest.fn()).toBeCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 0

    > 29 |     expect(appListenSpy).toBeCalledTimes(1);
Share Improve this question asked Feb 28, 2020 at 11:46 Mr.Mr. 10.2k14 gold badges67 silver badges91 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 5

Update: Using jest.mock in each test case the functional scope is possible, but you should import/require the module after calling jest.mock().

You can't use jest.mock in the function scope. It should be used in the module scope. Instead of using jest.mock inside the test case function, you should use jest.doMock(moduleName, factory, options)

E.g. server.js:

const express = require('express');
const app = express();

const server = app.listen(8080, '127.0.0.1').on('error', (err) => {
  console.log(err);
});

module.exports = server;

server.test.js:

describe('60451082', () => {
  it('should pass', () => {
    const mError = new Error('network');
    const appMock = {
      listen: jest.fn().mockReturnThis(),
      on: jest.fn().mockImplementationOnce((event, handler) => {
        handler(mError);
      }),
    };
    jest.doMock('express', () => jest.fn(() => appMock));
    const logSpy = jest.spyOn(console, 'log');
    const express = require('express');
    require('./server');
    expect(express).toBeCalledTimes(1);
    expect(appMock.listen).toBeCalledWith(8080, '127.0.0.1');
    expect(appMock.on).toBeCalledWith('error', expect.any(Function));
    expect(logSpy).toBeCalledWith(mError);
  });
});

Unit test results with 100% coverage:

 PASS  stackoverflow/60451082/server.test.js
  60451082
    ✓ should pass (19ms)

  console.log node_modules/jest-environment-enzyme/node_modules/jest-mock/build/index.js:866
    Error: network
        at Object.<anonymous> (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/stackoverflow/60451082/server.test.js:3:20)
        at Object.asyncJestTest (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
        at resolve (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
        at new Promise (<anonymous>)
        at mapper (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
        at promise.then (/Users/ldu020/workspace/github./mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
        at process._tickCallback (internal/process/next_tick.js:68:7)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |     100 |      100 |     100 |     100 |                   
 server.js |     100 |      100 |     100 |     100 |                   
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        4.444s, estimated 10s

source code: https://github./mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60451082

发布评论

评论列表(0)

  1. 暂无评论