11

我正在尝试测试一个反应组件并使用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测试代码中的节点实际上是隐藏的,因为它的父级是一个带有 class 的 divdimmer具有 style display: none

根据jest-dom文档(由以下人员使用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>
4

1 回答 1

15

以下是作者本人的回答: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()
})

然后测试应该通过。

于 2018-10-16T02:52:51.843 回答