同様の質問( これ など)を調べましたが、提案された解決策は react-testing-library を使用するとうまくいきませんでした。
複数の子を受け取ることができるコンポーネントがあります。このコンポーネントは、独自のサイズとその子のサイズを計算して、レンダリングできる子の数を確認します。アプリケーションで使用すると問題なく動作します。
私の問題は、このコンポーネントを react-testing-library でレンダリングすると、コンポーネントのコンテナーが0 height
およびwidth
でレンダリングされることです。そのため、私のコンポーネントは、子をレンダリングするための使用可能なスペースがないことを理解します。
テスト内で カスタムコンテナー を定義しようとしました。いくつかのスタイルを強制してwidth
とheight
を設定しようとしました;しかし、どれもうまくいきませんでした。
それを「修正」する方法はありますか?
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 の例。
そのプロパティを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
をモックしているようです。テスト環境から実際のスタイル(オフセットサイズなど)を計算することは期待していません。
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)
})