【发布时间】:2018-07-16 11:59:06
【问题描述】:
场景
尝试使用 Jest(和 Enzyme)测试一个简单的 React 组件。这个组件使用react-dropzone,我想测试一些涉及DOM的操作,所以我使用jsdom(已经由create-react-app配置)
问题
document 对象虽然在我的测试代码中可用并且在组件内部也可用,但在 dropzone onDrop 回调内部是 undefined,它会阻止测试运行。
代码
MyDropzone
import React from 'react'
import Dropzone from 'react-dropzone'
const MyDropzone = () => {
const onDrop = ( files ) =>{
fileToBase64({file: files[0]})
.then(base64Url => {
return resizeBase64Img({base64Url})
})
.then( resizedURL => {
console.log(resizedURL.substr(0, 50))
})
}
return (
<div>
<Dropzone onDrop={onDrop}>
Some text
</Dropzone>
</div>
);
};
const fileToBase64 = ({file}) => {
return new Promise((resolve, reject) => {
const reader = new FileReader()
reader.onload = () => {
return resolve(reader.result)
}
reader.onerror = (error) => {
return reject(error)
}
reader.readAsDataURL(file)
})
}
/**
* Resize base64 image to width and height,
* keeping the original image proportions
* with the width winning over the height
*
*/
const resizeBase64Img = ({base64Url, width = 50}) => {
const canvas = document.createElement('canvas')
canvas.width = width
const context = canvas.getContext('2d')
const img = new Image()
return new Promise((resolve, reject) => {
img.onload = () => {
const imgH = img.height
const imgW = img.width
const ratio = imgW / imgH
canvas.height = width / ratio
context.scale(canvas.width / imgW, canvas.height / imgH)
context.drawImage(img, 0, 0)
resolve(canvas.toDataURL())
}
img.onerror = (error) => {
reject(error)
}
img.src = base64Url
})
}
export default MyDropzone;
MyDropzone.test.jsx
import React from 'react'
import { mount } from 'enzyme'
import Dropzone from 'react-dropzone'
import MyDropzone from '../MyDropzone'
describe('DropzoneInput component', () => {
it('Mounts', () => {
const comp = mount(<MyDropzone />)
const dz = comp.find(Dropzone)
const file = new File([''], 'testfile.jpg')
console.log(document)
dz.props().onDrop([file])
})
})
setupJest.js
import { configure } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
configure({ adapter: new Adapter() })
配置
- 默认
create-react-app开玩笑配置setupJest.js添加到setupFiles - 运行:纱线测试
错误
TypeError: Cannot read property 'createElement' of undefined
at resizeBase64Img (C:\dev\html\sandbox\src\MyDropzone.jsx:44:29)
at fileToBase64.then.base64Url (C:\dev\html\sandbox\src\MyDropzone.jsx:8:20)
at <anonymous>
at process._tickCallback (internal/process/next_tick.js:188:7)
更多信息
如果在浏览器中运行该代码,则始终定义 document,所以对我来说,这个问题似乎与 jsdom 或 Jest 有关。
我不确定它是否与 Promises、FileReaded 或一般的 JS 范围有关。
也许是 Jest 方面的错误?
【问题讨论】:
-
我在使用 jest 读取磁盘上的文件时遇到了同样的问题。
-
开玩笑设置中的一切都是正确的。在测试环境中使用 jsdom 作为文档。除了在其他地方定义文档的地方文档为 null 的内部承诺。
-
@Zword,你能提供一个最小的调试仓库吗?它会更快
-
@TarunLalwani here ya go。有趣的是,我发现这很容易用 JS 应用程序重现,但不能用 TS app。
标签: javascript reactjs jestjs enzyme jsdom