はじめに
フォームのテストを行なってた時にプルダウンの値のテストでエラーが出ました。
テストするコードは以下です.chakra UIを使ってます
<Field.Root>
<Select.Root collection={skillsOptions} multiple={true} {...register('skills', { required: 'スキルは必須です' })} data-testid="register-select">
<Select.HiddenSelect />
<Select.Label htmlFor="skills">スキル</Select.Label>
<Select.Control>
<Select.Trigger>
<Select.ValueText placeholder="Select option" />
</Select.Trigger>
<Select.IndicatorGroup>
<Select.Indicator />
</Select.IndicatorGroup>
</Select.Control>
<Portal>
<Select.Positioner>
<Select.Content>
{skillsOptions.items.map((skill: SkillsOptions) => (
<Select.Item item={skill} key={skill.value}>
{skill.label}
<Select.ItemIndicator />
</Select.Item>
))}
</Select.Content>
</Select.Positioner>
</Portal>
</Select.Root>
{errors.skills && (
<Text role="alert" aria-live="polite" data-testid="register-error-select" style={{ color: 'red' }} textStyle="sm">
{errors.skills.message}
</Text>
)}
</Field.Root>
問題
テストのエラー箇所は以下です。
fireEvent.change(selectSkills, { target: { value: 'React, TypeScript' } });
エラーは以下です
Error: The given element does not have a value setter ❯ setNativeValue node_modules/@testing-library/dom/dist/events.js:131:13 ❯ createEvent node_modules/@testing-library/dom/dist/events.js:41:5 ❯ Function.createEvent.<computed> [as change] node_modules/@testing-library/dom/dist/events.js:106:38 ❯ Function.fireEvent.<computed> [as change] node_modules/@testing-library/dom/dist/events.js:110:68 ❯ Function.fireEvent.<computed> [as change] node_modules/@testing-library/react/dist/fire-event.js:15:52 ❯ src/tests/Register.test.jsx:81:15 79| fireEvent.change(inputUserName, { target: { value: 'テストユーザー' } }); 80| fireEvent.change(textAreaDescription, { target: { value: '<p>これはテスト用の自己紹介です</p>' } }); 81| fireEvent.change(selectSkills, { target: { value: 'React, TypeScript' } }); | ^ 82| fireEvent.change(inputGithubId, { target: { value: 'testGithub' } }); 83| fireEvent.change(inputQiitaId, { target: { value: 'testQiita' } });
このエラーの原因はfireEvent.change() を当てている要素が 「value を持つネイティブ要素(input / select / textarea)」ではないということでした。
最初は っぽいなと思ったのですが、実際の出力を見たら実体は div/ばとんでした。つまり入力系のHTMLではないってことですね。
解決方法
<Select.Root /* multiple なら multiple */>
<Select.HiddenSelect data-testid="skills-select" />
</Select.Root>
<Select.HiddenSelect data-testid="skills-select" />このタグにdata-testidを入れれば解決でした。
おわりに
Select.HiddenSelect は、見た目の Select(Trigger/Button + List)とは別に、内部でネイティブ を保持してフォーム連携や互換性を担うための要素です。フォームライブラリ連携のためにこれを公開している、という位置づけらしいです。
参考