Использование sinon для проверки функции в обещании - PullRequest
0 голосов
/ 23 ноября 2018

Я пытаюсь протестировать слой доступа к данным 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()
    })
})

Если я запускаю это, тайм-аут блока асинхронного теста.Кто-нибудь знает, как я должен это заглушить?

Спасибо!

1 Ответ

0 голосов
/ 23 ноября 2018

Issue

db.all не возвращает Promise, он использует обратный вызов в качестве второго аргумента.

stub.resolves заставляет заглушку вернуть Promiseтаким образом, обратный вызов никогда не вызывается, и обещание, возвращаемое selectMultiple, никогда не разрешается, вызывая таймаут теста на 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.

...