首页 > 解决方案 > 使用 sinon 测试 promise 中的函数

问题描述

我正在尝试测试 mysqlite3 数据访问层,但我似乎无法正确存根我的 db.all() 方法,我不确定这是由于我的数据库是如何传入的,还是我存根错误。

这是我的数据库文件:

const db = new sqlite3.Database(path.join(__dirname, ' 
../database/example.db'), (err) => {
    if (err) return console.log(err.message)
    console.log('Connected to the database')
})

module.exports.database = db

这是我试图存根的函数:

const db = require('./database.js').database

module.exports.selectMultiple = request => {
    //unimportant code
    return new Promise((resolve, reject) => {
        db.all(sql, (err, rows) => {
            if (err)
                reject(err)
            else {
                resolve('blah blah blah')
        })
    })
}

这是我似乎无法工作的尝试:

const db = require('../../data_access/database.js').database

describe('select multiple', () => {
    beforeEach(() => {
        const testProduct2 = JSON.parse(JSON.stringify(testProduct))
        testProduct2['key'] = '2'
        this.multiple = sinon.stub(db, 'all')
            .resolves([testProduct, testProduct2])
    })

    afterEach(() => {
        this.multiple.restore()
    })

    test('select 2 products', async(done) => {
        expect.assertions(2)
        const macbooks = await productDb.selectMultiple({amount: 2})
        expect(macbooks.length === 2).toBe(true)
        expect(macbooks[0].key !== macbooks[1].key).toBe(true)
        done()
    })
})

如果我运行这个异步测试块超时。有谁知道我应该如何解决这个问题?

谢谢!

标签: javascriptnode.jsjestjssinon

解决方案


问题

db.all不返回 Promise,它使用回调作为第二个参数。

stub.resolves导致存根返回 Promise,因此永远不会调用回调,并且永远selectMultiple不会解决返回的 Promise 导致测试超时await productDb.selectMultiple({ amount: 2 })

解决方案

存根db.all使用stub.callsArgWith以便调用作为第二个参数传递的回调:

describe('select multiple', () => {
  beforeEach(() => {
    const testProduct2 = JSON.parse(JSON.stringify(testProduct))
    testProduct2['key'] = '2'
    this.multiple = sinon.stub(db, 'all')
      .callsArgWith(1, null, [testProduct, testProduct2]);  // use stub.callsArgWith
  })

  afterEach(() => {
    this.multiple.restore()
  })

  test('select 2 products', async () => {
    expect.assertions(2)
    const macbooks = await productDb.selectMultiple({ amount: 2 })
    expect(macbooks.length === 2).toBe(true)  // SUCCESS
    expect(macbooks[0].key !== macbooks[1].key).toBe(true)  // SUCCESS
  })
})

另请注意,您不需要使用done,因为您正在使用async测试功能并await在调用productDb.selectMultiple.


推荐阅读