无法为语义 UI 反应组件检查 expect(elm).not.toBeVisible()
Posted
技术标签:
【中文标题】无法为语义 UI 反应组件检查 expect(elm).not.toBeVisible()【英文标题】:Cannot check expect(elm).not.toBeVisible() for semantic-ui react component 【发布时间】:2019-03-19 16:36:36 【问题描述】:我正在尝试测试一个反应组件并使用 expect(elm).not.toBeVisible()
没有成功。
更新 3
我已将代码缩减为这种更简单的形式:
// ./TestItem.js
import React from 'react'
import './TestItem.css'
export default ( hide ) =>
return <div className=hide ? 'shouldHide' : ''>Text</div>
// ./__tests__/TestItem.test.js
import React from 'react'
import render from 'react-testing-library'
import TestItem from '../TestItem'
import 'jest-dom/extend-expect'
import 'react-testing-library/cleanup-after-each'
test.only('TestItem should render correctly', async () =>
const getByText, debug = render(<TestItem hide=true />)
const itemNode = getByText('Text')
debug()
expect(itemNode).not.toBeVisible()
)
// ./TestItem.css
.shouldHide
display: none;
测试结果:
TestItem should render correctly
expect(element).not.toBeVisible()
Received element is visible:
<div class="shouldHide" />
7 | const itemNode = getByText('Text')
8 | debug()
> 9 | expect(itemNode).not.toBeVisible()
| ^
10 | )
11 |
debug()
日志:
console.log node_modules/react-testing-library/dist/index.js:58
<body>
<div>
<div
class="shouldHide"
>
Text
</div>
</div>
</body>
更新 2:
好吧,这变得很奇怪,因为我在 codesanbox 上通过了测试,但在我的本地机器上仍然没有运气。
我原来的问题:
我使用 React、semantic-ui-react 和 react-testing-library。
代码如下:
// ComboItem.test.js
import React from 'react'
import ComboItem from '../ComboItem'
import render from 'react-testing-library'
import comboXoi from '../images/combo-xoi.jpg'
import 'path/to/semantic/semantic.min.css'
describe('ComboItem', () =>
test('should render', async () =>
const getByText, debug = render(
<ComboItem image=comboXoi outOfStock=false />
)
const outOfStockNotice = getByText('Out of stock')
debug()
expect(outOfStockNotice).not.toBeVisible()
)
)
// ComboItem.js
import React from 'react'
import Card, Image from 'semantic-ui-react'
export default ( image, outOfStock = false ) =>
return (
<Card>
<Image
src=image
dimmer=
active: outOfStock,
inverted: true,
'data-testid': 'combo-item-dimmer',
content: (
<span style= marginTop: 'auto', color: 'black' >
Out of stock
</span>
),
/>
</Card>
)
我得到的是这里的结果:
ComboItem › should render
expect(element).not.toBeVisible()
Received element is visible:
<span style="margin-top: auto; color: black;" />
at Object.test (src/app/screens/App/screens/SaleEntries/screens/CreateSaleEntry/screens/StickyRiceComboSelect/__tests__/ComboItem.test.js:14:34)
at process._tickCallback (internal/process/next_tick.js:68:7)
我尝试在浏览器上查看组件渲染结果,测试代码中的节点outOfStockNotice
实际上是隐藏的,因为它的父级是dimmer
类的div,具有display: none
的样式。
根据jest-dom
doc(testing-react-library
使用:
可见
如果满足以下所有条件,则元素可见:
它的 css 属性 display 没有设置为 none 它没有将其 css 属性可见性设置为隐藏或折叠 它的 css 属性 opacity 没有设置为 0 它的父元素也是可见的(依此类推直到 DOM 树的顶部)
请帮忙。我真的不知道这里会出什么问题。
更新:
我在这里包含debug()
的结果:
console.log node_modules/react-testing-library/dist/index.js:58
<body>
<div>
<div
class="ui card"
>
<div
class="ui image"
>
<div
class="ui inverted dimmer"
data-testid="combo-item-dimmer"
>
<div
class="content"
>
<span
style="margin-top: auto; color: black;"
>
Out of stock
</span>
</div>
</div>
<img
src="combo-xoi.jpg"
/>
</div>
</div>
</div>
</body>
【问题讨论】:
我认为你不应该这样做await getByText
。我认为这是一个同步功能。请把debug()
的结果也贴一下好吗?
@Gpx 我不认为它真正重要的是同步。他使用 await 并且它以相同的方式适用于异步和同步
@Gpx 你好,我已经更新了我的问题以包含debug()
结果。是的,你是对的,我一定是弄错了它的用法。但是在删除await
之后,我仍然得到同样的错误。请检查我更新的问题。谢谢。
调光器肯定没有激活。缺少“活动”课程。我猜 testing-react-library 的渲染与语义 UI 不同步。如果可能,请尝试等待元素不可见github.com/kentcdodds/react-testing-library#wait
@EduardJacko 感谢您的评论爱德华!我试过await wait(() => expect(outOfStockNotice).not.toBeVisible())
,但结果是一样的。我已经用 codesanbox 示例更新了这个问题。它适用于代码沙盒,但不适用于我的机器。任何想法为什么或如何解决这个问题?
【参考方案1】:
这里是the answer根据react-testing-library
的作者本人所说:
可能是 JSDOM 限制(在代码和框中,它在真实浏览器中运行)。实际上,问题在于css实际上并未加载到JSDOM中的文档中。如果是这样,那将起作用。如果你能想出一个自定义的 jest 转换,可以在测试期间将 css 文件插入到文档中,那么你已经准备好了。
因此,如果您使用 CSS-in-JS,这将起作用。
所以基本上测试中的import './TestItem.css'
部分将不起作用,因为JSDOM不会加载它,因此jest-dom
无法理解shouldHide
类意味着display: none
。
更新:
根据这个Stack Overflow thread,可以将css插入到jsdom中:
import React from 'react'
import render from 'react-testing-library'
import TestItem from '../TestItem'
import fs from 'fs'
import path from 'path'
test.only('TestItem should render correctly', async () =>
const cssFile = fs.readFileSync(
path.resolve(__dirname, '../TestItem.css'),
'utf8'
)
const container, getByText, debug = render(<TestItem hide=true />)
const style = document.createElement('style')
style.type = 'text/css'
style.innerhtml = cssFile
container.append(style)
const itemNode = getByText('Text')
debug()
expect(itemNode).not.toBeVisible()
)
然后测试应该通过了。
【讨论】:
以上是关于无法为语义 UI 反应组件检查 expect(elm).not.toBeVisible()的主要内容,如果未能解决你的问题,请参考以下文章
无法在反应 js 类组件中编辑 datetimepicker material-ui