web-dev-qa-db-ja.com

反応テストライブラリのコンテナサイズを定義する方法

同様の質問( これ など)を調べましたが、提案された解決策は react-testing-library を使用するとうまくいきませんでした。

複数の子を受け取ることができるコンポーネントがあります。このコンポーネントは、独自のサイズとその子のサイズを計算して、レンダリングできる子の数を確認します。アプリケーションで使用すると問題なく動作します。

私の問題は、このコンポーネントを react-testing-library でレンダリングすると、コンポーネントのコンテナーが0 heightおよびwidthでレンダリングされることです。そのため、私のコンポーネントは、子をレンダリングするための使用可能なスペースがないことを理解します。

テスト内で カスタムコンテナー を定義しようとしました。いくつかのスタイルを強制してwidthheightを設定しようとしました;しかし、どれもうまくいきませんでした。

それを「修正」する方法はありますか?

コンポーネント(この質問のために一部のコードを省略):

const ParentComponent = (props) => {
  const [visibleChildren, setVisibleChildren] = useState(0)
  const myself = useRef(null)

  useEffect(() => {
    const componentWidth = myself.current.offsetWidth;
    const childrenWidth = myself.current.children.reduce(
      // Returns the total children width
    )

    // Returns the number of children I can display
    const childrenAmount = calculateSpace()
    setVisibleChildren(childrenAmount)
  }, [myself])

  // Slice the array of children to display only the right amount
  slicedChildren = props.children.slice(0, visibleChildren)

  return (
    <div ref={myself}>
      {slicedChildren}
    </div>
  )
}

使用する:

<ParentComponent>
  <Child />
  <Child />
  <Child />
</ParentComponent>

テスト:

import React from 'react'
import {render} from '@testing-library/react'
import ParentComponent from '../ParentComponent'

test('Render component', () => {
  const { getAllByRole } = render(
    <ParentComponent>
      <Child />
      <Child />
      <Child />
    </ParentComponent>
  )

  expect(getAllByRole("Child").length).toEqual(3)
})

更新しました:

これを追加 codesandbox の例。

4
Bruno Monteiro

そのプロパティをHTMLElement.prototype

Object.defineProperties(window.HTMLElement.prototype, {
  offsetWidth: {
    get: function() { return this.tagName === 'SPAN' ? 100: 500}
  }
});

https://github.com/jsdom/jsdom/issues/135#issuecomment-68191941 への称賛

問題を調べてください、それは(2011年以来!)大げさな話がありますが、まだ開かれています

実を言うと、ロジックのテストの信頼性を高めるためにoffsetWidthをモックしているようです。テスト環境から実際のスタイル(オフセットサイズなど)を計算することは期待していません。

2
skyboyer

ParentComponentが親から高さを継承している場合は、テスト用に指定された幅と高さでdiv内にラップすることができるはずです。

つまり:

import React from 'react'
import {render} from '@testing-library/react'
import ParentComponent from '../ParentComponent'

test('Render component', () => {
  const { getAllByRole } = render(
    <div style={{ width: 500, height: 500 }}>
      <ParentComponent>
        <Child />
        <Child />
        <Child />
      </ParentComponent>
    </div>
  )

  expect(getAllByRole("Child").length).toEqual(3)
})
0
Ben Bud