如何用笑话模拟膝盖计数

How to mock knex count with jest

我正在尝试模拟 knex 连接以引发故障,这样我就可以涵盖流程中的异常情况。 我在这个 answer 上找到了一种在 de mocks 文件夹中模拟的方法,但我没有任何运气。我的查询是计算 table:

中有多少条目
const db = require("../db/Client");
const logger = require("../utils/Logger");

const createUser = async () => {
    return db("users")
        .count()
        .then(data => {
            return data[0].count;
        })
        .catch(error => {
            logger.error(JSON.stringify(error));
            return null;
        });
};

module.exports = createUser;

我正在尝试这样模拟:

module.exports = () => ({
    select: jest.fn().mockReturnThis(),
    then: jest.fn().mockImplementation(() => {
        throw new Error("I am an exception");
    })
});

但是,我得到的 db("users") 不是函数。 帮忙?

您可以使用 jest.mock(moduleName, factory, options) 手动模拟 db

例如 index.js:

const db = require('./db/client');

const createUser = async () => {
  return db('users')
    .count()
    .then((data) => {
      return data[0].count;
    })
    .catch((error) => {
      console.log(error);
      return null;
    });
};

module.exports = createUser;

./db/client.js:

// knex

index.test.js:

const createUser = require('./');
const db = require('./db/client');

jest.mock('./db/client', () => {
  const mKnex = { count: jest.fn() };
  return jest.fn(() => mKnex);
});

describe('60357935', () => {
  it('should count user', async () => {
    const mData = [{ count: 10 }];
    db().count.mockResolvedValueOnce(mData);
    const actual = await createUser();
    expect(actual).toBe(10);
  });

  it('should handle error', async () => {
    const mError = new Error('network');
    db().count.mockRejectedValueOnce(mError);
    const actual = await createUser();
    expect(actual).toBeNull();
  });
});

100% 覆盖率的单元测试结果:

 PASS  Whosebug/60357935/index.test.js (5.972s)
  60357935
    ✓ should count user (11ms)
    ✓ should handle error (65ms)

  console.log Whosebug/60357935/index.js:2895
    Error: network
        at /Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/Whosebug/60357935/index.test.js:18:20
        at step (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/Whosebug/60357935/index.test.js:33:23)
        at Object.next (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/Whosebug/60357935/index.test.js:14:53)
        at /Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/Whosebug/60357935/index.test.js:8:71
        at new Promise (<anonymous>)
        at Object.<anonymous>.__awaiter (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/Whosebug/60357935/index.test.js:4:12)
        at Object.<anonymous> (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/Whosebug/60357935/index.test.js:17:29)
        at Object.asyncJestTest (/Users/ldu020/workspace/github.com/mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:100:37)
        at resolve (/Users/ldu020/workspace/github.com/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.com/mrdulin/react-apollo-graphql-starter-kit/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
        at promise.then (/Users/ldu020/workspace/github.com/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 |                   
 index.js |     100 |      100 |     100 |     100 |                   
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        7.484s

另一种选择是使用 knex-mock-client,它将真实的数据库连接替换为假的。

const knex = require('knex');
const { getTracker, MockClient } = require('knex-mock-client';
const createUser = require('./');
const db = require('./db/client');

jest.mock('./db/client', () => {
  return {
    db: knex({ client: MockClient })
  };
});

describe('60357935', () => {
  let tracker;

  beforeAll(() => {
    tracker = getTracker();
  });

  afterEach(() => {
    tracker.reset();
  });

  it('should count user', async () => {
    const mData = { count: 10 };
    tracker.on.select('users').responseOnce([mData]);

    const actual = await createUser();
    expect(actual).toBe(mData.count);
  });

  it('should handle error', async () => {
    const mError = new Error('network');
    tracker.on.select('users').simulateErrorOnce('network');

    const actual = await createUser();
    expect(actual).toBeNull();
  });
});