関連記事
Goメモ-464 (iotestパッケージのメモ)(01-TestReader) - いろいろ備忘録日記
GitHub - devlights/blog-summary: ブログ「いろいろ備忘録日記」のまとめ
概要
以下、自分用のメモです。忘れないうちにメモメモ。。。
以下の書籍で知ったのですが、testing/iotest
というパッケージの存在を知りました。こんなのあったんですね。
このパッケージの中には、io.Readerやio.Writerを受け取り処理する関数をテストする際に便利な関数なども用意されています。
今回は、iotest.ErrReader
関数について。
iotest.ErrReader
関数は、常にエラーを返す io.Reader です。io.Readerを受け取って処理する関数のエラー処理のテストなどに使えます。
サンプル
read.go
package errreader import ( "errors" "io" "syscall" "time" ) var ( Interval = 10 * time.Millisecond ErrTooManyEAGAIN = errors.New("retry over (EAGAIN)") MaxRetryCount = 5 ) func read(r io.Reader, p []byte) error { var ( buf = make([]byte, 2) numRead int offset int count int err error ) for count = 0; count < MaxRetryCount; { if len(p) <= offset { break } clear(buf) numRead, err = r.Read(buf) if err != nil { switch { case errors.Is(err, io.EOF): break case errors.Is(err, syscall.EAGAIN): time.Sleep(Interval) count++ continue default: return err } } copy(p[offset:offset+numRead], buf[:numRead]) offset += numRead } if MaxRetryCount <= count { return ErrTooManyEAGAIN } return nil }
errreader_test.go
package errreader import ( "errors" "strings" "syscall" "testing" "testing/iotest" ) func TestReadOk(t *testing.T) { var ( s = "hello world" r = strings.NewReader(s) p = make([]byte, len(s)) err error ) err = read(r, p) if err != nil { t.Fatal(err) } if string(p) != s { t.Fatalf("[want] equal\t[got] not equal (%s, %s)", string(p), s) } } func TestReadTooManyEAGAIN(t *testing.T) { // // iotest.ErrReader() は、指定したエラーを返す io.Reader を返してくれる。 // io.Readerを使って何らかの処理を行う関数などを実装している場合のエラーテストに便利。 // (例えば、ノンブロッキング処理をしている実装で、ずっとEAGAINが返ってくる場合のテストなど) // // - https://pkg.go.dev/testing/iotest@go1.23.0#ErrReader // var ( s = "hello world" r = iotest.ErrReader(syscall.EAGAIN) p = make([]byte, len(s)) ) err := read(r, p) if err == nil { t.Fatal("[want] err \t[got] nil") } if !errors.Is(err, ErrTooManyEAGAIN) { t.Fatalf("[want] ErrRetryOver\t[got] %v", err) } }
実行すると以下のようになります。
$ task task: [default] go test -v . === RUN TestReadOk --- PASS: TestReadOk (0.00s) === RUN TestReadTooManyEAGAIN --- PASS: TestReadTooManyEAGAIN (0.05s) PASS ok github.com/devlights/try-golang/examples/singleapp/iotest/errreader 0.054s
参考情報
Goのおすすめ書籍
過去の記事については、以下のページからご参照下さい。
サンプルコードは、以下の場所で公開しています。