JS / JestJS:如何测试异步模拟函数?

时间:2018-01-22 18:26:49

标签: javascript unit-testing jestjs

正如您在我的测试文件中看到的那样,我嘲笑了所有mongoDB方法。

现在我需要测试,如果已调用Content.update()。在这个示例代码中,我正在测试一个正在运行但不想要的被调用的console.log。 我不明白为什么我无法测试update()

/category.test.js

import { updateCategory } from './category'
import DB from './lib/db'

test('should update document', async () => {
  DB.getDB = jest.fn(
    () => ({
      get: jest.fn(
        () => ({
          findOne: jest.fn(() => ({ some: 'content' })),
          update: jest.fn()
        })
      )
    })
  )
  console.log = jest.fn()

  return updateCategory({}, {
    id: '12345678901234567'
  }).then(() => {
    expect(console.log).toHaveBeenCalled()
    // instead check if `Content.update()` has been called
    expect(DB.getDB().get().update).toHaveBeenCalled() // throws `Expected mock function to have been called.`
  })
})

/category.js

import DB from './lib/db'

export async function updateCategory (obj, { id }) {
  const db = DB.getDB()
  const Content = db.get('content')
  const doc = await Content.findOne({ _id: id })

  console.log('ok');

  await Content.update(
    { _id: id },
    { $set: { category: 'new category' } }
  )
}

1 个答案:

答案 0 :(得分:3)

将您要监视的模拟存储在变量中,以便跟踪它:

import { updateCategory } from './category'
import DB from './lib/db'
jest.mock('./lib/db');

const mockUpdate = jest.fn();

test('should update document', async () => {
  DB.getDB.mockImplementation( // <-- available when you call jest.mock above, seems safer than overwriting the implementation in the real import
    () => ({
      get: jest.fn(
        () => ({
          findOne: jest.fn(() => ({ some: 'content' })),
          update: mockUpdate
        })
      )
    })
  )
  console.log = jest.fn()

  return updateCategory({}, {
    id: '12345678901234567'
  }).then(() => {
    expect(console.log).toHaveBeenCalled()
    // instead check if `Content.update()` has been called
    expect(mockUpdate).toHaveBeenCalled() // should work now
  })
})