javascript - 在 React 模块中测试 SweetAlert2 的 preConfirm 钩子
问题描述
具有这样的 React 模块名称Modal
:
import withReactContent from 'sweetalert2-react-content'
export const Modal = withReactContent(Swal)
const showModal = props => {
return Modal.fire({
...props,
showCloseButton: true
})
}
export default showModal
在另一个组件中用作用户操作的确认框
export const renderDeployModal = (deploymentId) => {
console.log(' - renderDeployModal - ')
Modal.fire({
type: 'question',
text: `Are you sure you wish to re-deploy this (${deploymentId})?`,
showCancelButton: true,
confirmButtonText: 'Deploy',
preConfirm: () => {
console.log(' - preConfirm - ')
return apiRequest(`/deployments/${deploymentId}/trigger`, {}, 'POST')
.then(response => {
return response.body
})
.catch(response => {
Modal.showValidationMessage(response.message)
})
},
allowOutsideClick: () => !Modal.isLoading()
}).then(result => {
if (result.value) {
notify('success', 'Your deployment has triggered.')
}
})
}
实现工作,但我被困在测试preConfirm
钩子中执行的逻辑,因为我想不出任何方法来Modal.clickConfirm()
手动触发我的测试并实际工作
import * as mockModal from '../../modal'
jest.mock('../../modal')
describe('renderDeployModal', () => {
it('fails to run a deploy without deploymentId argument', async () => {
const Modal = mockModal.Modal.mockImplementationOnce()
Modal.fire.mockImplementationOnce(() => Promise.resolve({ value: false }))
Modal.clickConfirm = jest.fn()
// Modal.clickConfirm.mockImplementation(() => Promise.resolve())
// const spy = jest.spyOn(mockModal.Modal, 'clickConfirm')
apiRequest.default = jest.fn().mockReturnValue(Promise.reject(new Error('foo')))
await renderDeployModal(null)
await Promise.resolve()
Modal.clickConfirm()
await Promise.resolve()
expect(Modal.fire).toHaveBeenCalled()
expect(Modal.clickConfirm).toHaveBeenCalled()
expect(apiRequest.default).toHaveBeenCalledWith(`/deployments/null/trigger`, {}, 'POST')
})
上面的测试在预期的最后一次失败apiRequest
。
console.log src/actions.js:111
- renderDeployModal -
FAIL src/actions.test.js
...
✕ fails to run a deploy without deploymentId argument (56ms)
● renderDeployModal › fails to run a deploy without deploymentId argument
expect(jest.fn()).toHaveBeenCalledWith(expected)
Expected mock function to have been called with:
["/deployments/null/trigger", {}, "POST"]
But it was not called.
148 | expect(Modal.fire).toHaveBeenCalled()
149 | expect(Modal.clickConfirm).toHaveBeenCalled()
> 150 | expect(apiRequest.default).toHaveBeenCalledWith(`/deployments/null/trigger`, {}, 'POST')
| ^
也console.log(' - renderDeployModal - ')
显示,但console.log(' - preConfirm - ')
不显示,表明Modal.clickConfirm()
未正确触发。
我在这里想念什么?我没有想法(好或坏)可以尝试。
解决方案
每当您像以前一样模拟模块时
jest.mock('../../modal')
它为模块对象对象的每个属性创建模拟函数,而无需实现。
因此,您将一个对象传递给Modal.fire()
具有回调的对象preConfirm
,但没有什么应该调用它。因此,您可能应该将模拟实现更改为:
Modal.fire.mockImplementationOnce(({ preConfirm }) => {
preConfirm(); // <- execute the given callback
return Promise.resolve({ value: false })
})
然后期望它被调用
旁注:顺便说一句,没有意义
test('if I call a function it`s actually being called', () => {
Modal.clickConfirm() // <- execute a function within the test
expect(Modal.clickConfirm).toHaveBeenCalled() // and make sure it have been called few lines below
});
推荐阅读
- apache-spark - Pyspark 作业队列配置优先级 - spark-submit vs SparkSession.builder
- javascript - 通过 api 端点访问特定项目
- javascript - React Jsx - 如何为随机报价生成器挂钩 RxJs 点击事件?
- python - 相同数据集和超参数的差异 betweek Keras 和 Tensorflow
- reactjs - 反应内存泄漏,componentDidUnmount 不起作用
- c# - 插入数据时在 xamarin 表单中出现错误:System.ArgumentNullException:'值不能为空。参数名称:取消'
- ffmpeg - 您如何将特定 X 和 Y 位置的视频与 FFMPEG 结合起来?
- java - 如何将 JSON 添加到项目的类路径中?使用 VS 代码
- ruby-on-rails - /profile 之类的路径是否生成正确的 URI?他们违反了 REST 吗?有什么影响?
- python - 用于 Awk 的 Python 子进程