使用Jest模拟命名导入

时间:2017-10-15 23:38:56

标签: react-native jestjs expo es6-modules

我有一个'notifications.js'模块看起来有点像这样:

import { Notifications, Permissions } from 'expo'

export function setLocalNotification(storage = AsyncStorage) {
  return storage
    .getItem(NOTIFICATION_KEY)
    .then(JSON.parse)
    .then(data => {
      if (data === null) {
        return Permissions.askAsync(
          Permissions.NOTIFICATIONS
        ).then(({ status }) => {
          if (status === 'granted') {
            Notifications.cancelAllScheduledNotificationsAsync()
            ...etc.

在我的测试中,我想模拟权限和通知,以便我可以在notifications.spec.js中执行类似的操作:

import { setLocalNotification } from './notifications'
import mockAsyncStorage from '../mock/AsyncStorage'

it('correctly cancels pending notifications', done => {
  setLocalNotification(mockAsyncStorage).then(done())
  expect(Permissions.askAsync).toBeCalled()
  expect(Notifications.cancelAllScheduledNotificationsAsync)
    .toBeCalled()
})

我使用jest.mockjest.setMock尝试了各种各样的事情,但我似乎无法使其发挥作用。我如何以所需的方式模拟这些命名的导入?例如,我试过这个:

jest.setMock('Permissions', () => ({
  askAsync: jest
    .fn()
    .mockImplementationOnce(() => ({ status: 'granted' }))
}))

但这不起作用。它抛出

'module Permissions cannot be found from notifications.spec.js'

如果我尝试模拟整个expo模块,模拟函数expect().toBeCalled()将返回false。

1 个答案:

答案 0 :(得分:3)

您必须模拟模块'expo'

jest.mock('expo', ()=>({
  Permissions: {
     askAsync: jest.fn()
  }
}))