質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

5183閲覧

React-Testing-libraryでのテストでWarning警告文を無くしたい

kiyomasa

総合スコア40

ユニットテスト

ユニットテストは、システムのテスト手法の一つで、個々のモジュールを対象としたテストの事を指します。対象のモジュールが要求や性能を満たしているか確認する為に実行します。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2021/09/23 01:12

前提・実現したいこと

現在、ポートフォリオ を作成中で、React-Testing-Libraryを使って、テストコードを記述しています。
画像ファイルのアップロードが正しく行われているか?のテストをググりながら実装し、記載したところ、
テストはパスするものの、以下の警告文が発生してしまいました。

独学初学者で基礎が未熟ですが、この警告文が出ないようにするための方策をご教授いただけるとありがたいです。

発生している問題・エラーメッセージ

javascript

1Warning: You seem to have overlapping act() calls, this is not supported. 2Be sure to await previous act() calls before making a new one. 3 4act(() => { 5 /* fire events that update state */ 6 }); 7 /* assert on the output */ 8 9This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act 10 11 12 83 | <Image src={!avatar.data ? "gibbresh.png" : avatar.data} fallbackSrc="https://via.placeholder.com/250" boxSize={{ base: "250px", md: "300px" }} borderRadius="full" textAlign="center" border="2px" borderColor="gray.200"/> 13 84 | </Stack> 14 > 85 | <Stack> 15 | ^ 16 86 | <Input type="file" placeholder="画像アップロード" name="avatar" id="avatar" accept="image/png,image/jpeg" onChange={handleImageSelect} /> 17 87 | </Stack>

該当のソースコード

テストするReactのコード

javascript

1import React, { memo, useState } from "react"; 2import { Box, Divider, Flex, Heading, Input, Stack, Text, Image, FormLabel } from "@chakra-ui/react"; 3import styled from 'styled-components'; 4import { useForm } from 'react-hook-form'; 5import { yupResolver } from "@hookform/resolvers/yup"; 6import * as yup from "yup"; 7 8import { useSignup } from "../hooks/useSignup"; 9 10const schema = yup.object().shape({ 11 name: yup.string().max(50,"名前は50文字以内で入力して下さい").required("名前は必須です"), 12 email: yup.string().email('正しいメールアドレスを入力してください').required("emailは必須です"), 13 password: yup.string().min(4,"passwordは4文字以上で入力して下さい").max(15,"passwordは15文字以内で入力して下さい").required("パスワードは必須です"), 14 password_confirmation: yup.string().oneOf([yup.ref("password"), null], '再入力passwordが一致しません'), 15}); 16 17export const Signup = memo(() => { 18 const { signup } = useSignup(); 19 const { register, handleSubmit, formState: { errors } } = useForm({ 20 resolver: yupResolver(schema), 21 }); 22 23 const [avatar, setAvatar] = useState({ data: "", name: "" }) 24 25 const onSubmit = (data) => { 26 signup(data,avatar); 27 } 28 29 const handleImageSelect = (e) => { 30 const reader = new FileReader() 31 const files = (e.target).files 32 if (files) { 33 reader.onload = () => { 34 setAvatar({ 35 data: reader.result, 36 name: files[0] ? files[0].name : "unknownfile" 37 }) 38 } 39 reader.readAsDataURL(files[0]) 40 } 41 } 42 return ( 43 <> 44 <Flex mt="80px" alignItems="center" justifyContent="center"> 45 <Box bg="white" w="sm" p={4} borderRadius="md" shadow="md"> 46 <Heading as="h1" size="lg" textAlign="center"> 47 新規登録 48 </Heading> 49 <Divider my={4} /> 50 <form onSubmit={handleSubmit(onSubmit)}> 51 <Stack spacing={6} py={4} px={5}> 52 <Input type="text" placeholder="name" {...register("name")} /> 53 <Text fontSize="md" color="red"> {errors.name?.message} </Text> 54 55 <Input 56 type="text" placeholder="email" {...register("email")}/> 57 <Text fontSize="md" color="red"> {errors.email?.message} </Text> 58 <Input 59 type="password" placeholder="password" {...register("password")}/> 60 <Text fontSize="md" color="red"> {errors.password?.message} </Text> 61 <Input type="password" placeholder="password(確認用)" {...register("password_confirmation")}/> 62 <Text fontSize="md" color="red"> {errors.password_confirmation?.message} </Text> 63 64 <Stack> 65 <FormLabel color="gray.500" htmlFor="avatar" mt="4" mb="-2" fontSize={{ base: "sm", md: "md" }}>アバター写真</FormLabel> 66 <Image src={!avatar.data ? "gibbresh.png" : avatar.data} fallbackSrc="https://via.placeholder.com/250" boxSize={{ base: "250px", md: "300px" }} borderRadius="full" textAlign="center" border="2px" borderColor="gray.200"/> 67 </Stack> 68 <Stack> 69 <Input type="file" placeholder="画像アップロード" name="avatar" id="avatar" accept="image/png,image/jpeg" onChange={handleImageSelect} /> 70 </Stack> 71 <SSubmit 72 type="submit" 73 value="新規登録" 74 /> 75 </Stack> 76 </form> 77 </Box> 78 </Flex> 79 </> 80 ); 81}); 82

fileのアップロードテストのコード

javascript

1describe('readFileAsDataURL()', () => { 2 it('upload file', async() => { 3 render(<Signup />) 4 const file = new File(['hello'], 'hello.png', { type: 'image/png' }) 5 const input = screen.getByLabelText("アバター写真") 6 userEvent.upload(input, file) 7 8 expect(input.files[0]).toStrictEqual(file) 9 expect(input.files.item(0)).toStrictEqual(file) 10 expect(input.files).toHaveLength(1) 11 }); 12});

参考にしたテストコードはこちらです
testing-library公式
https://testing-library.com/docs/ecosystem-user-event/#uploadelement-file--clickinit-changeinit--options

試したこと

①まずは警告文でググりました
https://github.com/testing-library/react-testing-library/issues/605

ここでの問題は、コードがfindBy *クエリの結果を待っていないことだと思います。
また、テスト関数は非同期である必要があります。
と記載を見つけました。

そこで

it('upload file', async() => { render(<Signup />) const file = new File(['hello'], 'hello.png', { type: 'image/png' }) const input = screen.getByLabelText("アバター写真") userEvent.upload(input, file) await expect(input.files[0]).toStrictEqual(file) await expect(input.files.item(0)).toStrictEqual(file) await expect(input.files).toHaveLength(1) });

とawaitを記述したところ何も変わりませんでした。

②警告文の指示通り、Reactの公式でactについて調べました
https://reactjs.org/link/wrap-tests-with-act

いまいち理解できてませんが、公式の例を参考に、

it('upload file', async() => { render(<Signup />) const file = new File(['hello'], 'hello.png', { type: 'image/png' }) const input = screen.getByLabelText("アバター写真") act(()=>{ userEvent.upload(input, file) }) await expect(input.files[0]).toStrictEqual(file) await expect(input.files.item(0)).toStrictEqual(file) await expect(input.files).toHaveLength(1) });

こうしたところ、でも何も変化なしでした。

③どこに原因があるのかをはっきりさせるため、
コメントアウトしながら警告が出るか調べたところ

userEvent.upload(input, file)

この記述が警告文を出していることが判明しました。
(この文をコメントアウトすると警告が止まるので。)

正直、これ以上次の手が考えられていません。
お知恵をいただけるとありがたいです

補足情報(FW/ツールのバージョンなど)

"react": "^17.0.2", "devDependencies": { "@testing-library/jest-dom": "^5.14.1", "@testing-library/react-hooks": "^7.0.2", "msw": "^0.35.0", "react-test": "^0.10.2"

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

stateを変更するような操作は、actのコールバックの中から行う必要があります。

javascript

1act(() => { 2 userEvent.upload(input, file); 3});

投稿2021/09/23 01:37

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kiyomasa

2021/09/23 06:28

ご教授いただきありがとうございます。 そのような書き方で記載も行いましたが、ワーニングは変わりませんでした...
maisumakun

2021/09/23 07:02

エラーメッセージに書かれているように、await act(後略としてみたら、どうなりますか?
kiyomasa

2021/09/23 08:30 編集

このように記載しました。 ``` await act(() => { userEvent.upload(input, file); }); ``` すると同じワーニングが出たのに加えて、別のワーニングが発生しました。 ``` Warning: Do not await the result of calling act(...) with sync logic, it is not a Promise. ```
maisumakun

2021/09/24 08:18

すみません、ちょっとわからない状況です。
guest

0

自己解決

テストコードを以下のようにしたところ解決しました。

await act(async() => { userEvent.upload(input, file); }); await waitFor(() => { expect(input.files[0]).toStrictEqual(file) expect(input.files.item(0)).toStrictEqual(file) expect(input.files).toHaveLength(1) });

actにasyncを入れてかつ、
waitForで関数実行を待つことで警告文は出なくなりました。

ありがとうございました。

投稿2021/10/09 02:26

kiyomasa

総合スコア40

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問