ウェブサイト検索

reactjs - react-testing-libraryでMUIのチェックボックスをテストする


Reactコンポーネントで、Material UIのチェックボックスが次のマークアップであります:

<label class="MuiFormControlLabel-root">
   <span class="MuiButtonBase-root MuiIconButton-root PrivateSwitchBase-root-353 MuiCheckbox-root MuiCheckbox-colorPrimary PrivateSwitchBase-checked-354 Mui-checked MuiIconButton-colorPrimary" aria-disabled="false">
      <span class="MuiIconButton-label">
         <input class="PrivateSwitchBase-input-356" id="citizen-profile-challenge-checkbox-diabetes" type="checkbox" data-indeterminate="false" value="other" checked="">
         <svg class="MuiSvgIcon-root" focusable="false" viewBox="0 0 24 24" aria-hidden="true">
            <path d="M19 3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.11 0 2-.9 2-2V5c0-1.1-.89-2-2-2zm-9 14l-5-5 1.41-1.41L10 14.17l7.59-7.59L19 8l-9 9z"></path>
         </svg>
      </span>
      <span class="MuiTouchRipple-root"></span>
   </span>
   <span class="MuiTypography-root MuiFormControlLabel-label MuiTypography-body1">Other</span>
</label>

IDを使うのではなく、ラベル(この場合は「その他」)でクエリすることで、ガイドラインに従おうとしています。

だから、「Other」というラベルのチェックボックス(<span class="MuiTypography-root MuiFormControlLabel-label MuiTypography-body1">Other</span>)をクリックして、チェックボックスの値が変わることをテストしたいです(<input class="PrivateSwitchBase-input-356" id="citizen-profile-challenge-checkbox-diabetes" type="checkbox" data-indeterminate="false" value="other" checked="">)。

fireEvent.click(getByLabelText('Other', { selector: 'input' }))
const checked1 = (getByLabelText('Other', { selector: 'input' }) as HTMLInputElement).checked
console.log(checked1) // false

fireEvent.click(getByLabelText('Other', { selector: 'input' }))
const checked2 = (getByLabelText('Other', { selector: 'input' }) as HTMLInputElement).checked
console.log(checked2) // false

fireEvent.click(getByLabelText('Other'))
const checked3 = (getByLabelText('Other') as HTMLInputElement).checked
console.log(checked3) // false

fireEvent.click(getByLabelText('Other'))
const checked4 = (getByLabelText('Other') as HTMLInputElement).checked
console.log(checked4) // false

いくつかの方法を試しましたが、checked は false のままです。どうやら代わりに、ラベルの span の兄弟要素を取得してそこを探す必要があるようです。しかし、それをどうやって行えばいいのでしょうか?

回答 #1

チェックボックスをクリックしても変わらない理由の可能な説明を見つけました…

チェックボックスは、親コンポーネントによって管理される制御された入力です。したがって、ここでクリックしても実際には状態は変わりません。その代わりに、単にコールバック関数(propsから渡された)onChangeが呼び出されます。したがって、これをテストする正しい方法は、コールバックが正しい引数とペイロードで呼び出されているかを確認することです。

同じような問題を抱えている他の人の助けになればと思います。

it('should clea field if "Other" is unchecked', (): void => {
    const citizen = {
        ...props.citizen,
        illnesses: [Challenge.Other],
        otherIllnesses: 'Blah...',
    }
    const { getByLabelText } = render(<CitizenProfileChallenges {...props} citizen={citizen} />)

    // arrange
    const checkboxLabel = 'Other'

    // act
    fireEvent.click(getByLabelText(checkboxLabel))

    // assert
    expect(props.onCitizenChange).toHaveBeenCalledTimes(1)
    expect(props.onCitizenChange).toHaveBeenCalledWith({
        ...
    })
})

回答 #2

あなたは単にaddEventListenerを使う必要があると思います。ここに例があります。

document.getElementById("citizen-profile-challenge-checkbox-diabetes")
        .addEventListener("change", function changeHandler() {
          console.log(this.checked ? "checked!!" : "unchecked!!");
        });