用笑话测试异步功能

时间:2020-04-16 23:37:13

标签: javascript node.js unit-testing jestjs

我正在尝试模拟数据库连接对象以进行测试,但即时获取的错误始终相同。

我已经尝试过其他解决方案,但是模拟总是返回相同的对象。经过一番重新尝试和更改,我找到了另一个类似的解决方案

// connection.js
/* istanbul ignore file */
const mysql = require('mysql');

let pool;
const config = require('./config.js');

const connection = getPool();
/**
 * Singleton pool connection
 * @return {Pool} the pool connection
 */
function getPool() {
  if (pool) {
    return pool;
  }
  pool = mysql.createPool(config);
  return pool;
}

module.exports = connection;
// database.js
const connection = require('./connection')
function find() {
  return new Promise((resolve, reject) => {
    const query = 'select * from table`;
    connection.query(query, (err, res) => {
      if (err) {
        reject(new DatabaseError('Error'));
      }
      resolve(res);
    });
  });
}

最后我的测试文件看起来像这样


const database = require('./database.js');
const connection = require('./connection.js');
const { expect } = chai;
const DatabaseError = require('../../../src/errors/DatabaseError');

jest.mock('./connection.js');
  describe('testing find all', () => {
    test('testing error ', async () => {
      connection.query.mockImplementation(() => (q,  cb) => cb(res, null, null));
      try {
        await database.find();
      } catch (e) {
      expect(err).to.be.an.instanceof(DatabaseError);
      }
    });
  });

我得到的错误总是相同的

    : Timeout - Async callback was not invoked within the 10000ms timeout specified by jest.setTimeout.Timeout - Async callback was not invoked within the 10000ms timeout specified by jest.setTimeout.Error:

      11 |   describe('test find all', () => {
    > 12 |     test('testing error ', async () => {

我已经尝试使用return语句和async done,但没有任何方法可以解决此问题

有什么帮助吗?

我使用mockimplementation的原因是因为我需要更改每个query值的测试

1 个答案:

答案 0 :(得分:1)

您应该像这样模拟connection.query方法的实现:

connection.query.mockImplementation((q, cb) => cb(mError, null));

看到区别了吗?您可以将其作为高阶函数来模拟。不对这是一个工作示例:

connection.js

/* istanbul ignore file */
const mysql = require('mysql');

let pool;
const config = require('./config.js');

const connection = getPool();
/**
 * Singleton pool connection
 * @return {Pool} the pool connection
 */
function getPool() {
  if (pool) {
    return pool;
  }
  pool = mysql.createPool(config);
  return pool;
}

module.exports = connection;

database.js

const connection = require('./connection');

function find() {
  return new Promise((resolve, reject) => {
    const query = 'select * from table';
    connection.query(query, (err, res) => {
      if (err) {
        return reject(new Error('Error'));
      }
      resolve(res);
    });
  });
}

module.exports = { find };

config.js

module.exports = {};

database.test.js

const database = require('./database.js');
const connection = require('./connection.js');

jest.mock('./connection.js');

describe('testing find all', () => {
  test('testing error ', async () => {
    const mError = new Error('network');
    connection.query.mockImplementation((q, cb) => cb(mError, null));
    try {
      await database.find();
    } catch (e) {
      expect(e).toBeInstanceOf(Error);
    }
  });
});

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

 PASS  stackoverflow/61261886/database.test.js (10.531s)
  testing find all
    ✓ testing error  (5ms)

-------------|---------|----------|---------|---------|-------------------
File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------|---------|----------|---------|---------|-------------------
All files    |   88.89 |       50 |     100 |   88.89 |                   
 config.js   |     100 |      100 |     100 |     100 |                   
 database.js |    87.5 |       50 |     100 |    87.5 | 10                
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        12.222s

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/61261886