不使用 NodeJS 连接到数据库的单元测试 Mysql

Unit test Mysql without connecting to database with NodeJS

我有一个 Conn class,用于使用 AWS IAM 身份验证和 运行 查询连接到 MySQL 数据库。我已经编写了 class 并且它工作正常,但是我在不访问数据库的情况下尝试测试它时遇到了很多困难。

这是康恩 Class:

const AWS = require('aws-sdk');
const mysql = require("mysql2/promise");

class Conn {
    constructor(options = {}) {
        this.options = options;
    }

    async getPool() {
        return mysql.createPool(this.options);
    }

    setToken () {
        this.signer = new AWS.RDS.Signer({
            region: 'us-east-1', // example: us-east-2
            hostname: this.options.host,
            port: 3306,
            username: this.options.user
        });

        this.token = this.signer.getAuthToken({
            username: this.options.user
        });
    }

    async setConnection () {
        this.dbOptions = {
            host     : this.options.host,
            user     : this.options.user,
            ssl: 'Amazon RDS',
            password: this.token,
            authPlugins: {
                mysql_clear_password: () => () => Buffer.from(this.token + '[=11=]')
            }
        };

        this.pool = await this.getPool(this.dbOptions);
        this.conn = await this.pool.getConnection();
    }

    async executeQuery () {
        this.dbResult = await this.conn.query("select 1 + 1 as solution");
        this.conn.release();
    }
}

module.exports = {
    Conn: Conn
}

我在这里尝试使用 sinon 测试 Conn.executeQuery 函数:

const { handler } = require("../src/conn");
const sinon = require("sinon");
const {expect: expects} = require("chai");
const connection = require('../src/conn');

describe("conn", () => {
    afterEach(() => {
        sinon.restore();
    });
    it("should test conn.executeQuery", async () => {
        const connStub = { query: sinon.stub().resolves({ rowCount: 1 }), release: sinon.stub() };
        const poolStub = { getConnection: sinon.stub().resolves(connStub) };
        const pool = {getPool: sinon.stub().resolves(poolStub)};
        const conn = new connection.Conn();
        await conn.setConnection();
        const actual = await conn.executeQuery()
        expects(actual).to.be.eql({ rowCount: 1 });
        sinon.assert.calledWith(connStub.query, "select 1 + 1 as solution");
        sinon.assert.calledOnce(connStub.release);
    });
});

不幸的是,这段代码产生的都是错误,例如

Error: connect ECONNREFUSED 127.0.0.1:3306

如何使用 sinon 测试 Conn.executeQuery 函数而不访问数据库?

单元测试解决方案:

Conn.js:

const mysql = require('mysql2/promise');

class Conn {
  constructor(options = {}) {
    this.options = options;
  }

  async getPool() {
    return mysql.createPool(this.options);
  }

  async setConnection() {
    this.dbOptions = {
      host: this.options.host,
      user: this.options.user,
      ssl: 'Amazon RDS',
      password: this.token,
      authPlugins: {
        mysql_clear_password: () => () => Buffer.from(this.token + '[=10=]'),
      },
    };

    this.pool = await this.getPool(this.dbOptions);
    this.conn = await this.pool.getConnection();
  }

  async executeQuery() {
    this.dbResult = await this.conn.query('select 1 + 1 as solution');
    this.conn.release();
  }
}

module.exports = { Conn };

Conn.test.js:

const { Conn } = require('./Conn');
const sinon = require('sinon');
const mysql = require('mysql2/promise');

describe('64112250', () => {
  afterEach(() => {
    sinon.restore();
  });
  it('should test conn.executeQuery', async () => {
    const poolStub = {
      getConnection: sinon.stub().returnsThis(),
      query: sinon.stub().returnsThis(),
      release: sinon.stub(),
    };
    const createPoolStub = sinon.stub(mysql, 'createPool').returns(poolStub);
    const conn = new Conn();
    await conn.setConnection();
    await conn.executeQuery();
    sinon.assert.calledOnce(createPoolStub);
    sinon.assert.calledOnce(poolStub.getConnection);
    sinon.assert.calledWithExactly(poolStub.query, 'select 1 + 1 as solution');
    sinon.assert.calledOnce(poolStub.release);
  });
});

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

  64112250
    ✓ should test conn.executeQuery


  1 passing (24ms)

----------|---------|----------|---------|---------|-------------------
File      | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------|---------|----------|---------|---------|-------------------
All files |   81.82 |      100 |   66.67 |      90 |                   
 Conn.js  |   81.82 |      100 |   66.67 |      90 | 19                
----------|---------|----------|---------|---------|-------------------