1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

require.ErrorIsでエラーが一緒に見えるのに通らない時に見て欲しいこと[Go]

Posted at

goでtestをしているときにtestifyパッケージのrequire.ErrorIsでメソッドを用いて、エラーの検証がしたいときに、下のようなエラーが発生したことがありました。

return fmt.Errorf("error: %s", gorm.ErrNotFound)
require.ErrorIs(t, err, tt.wantErr)

エラーをよく見ると欲しいエラー文と実際のエラー文が同じなのに、テストが通りませんでした。

--- FAIL: TestUpdate (0.00s)
    --- FAIL: TestUpdate (0.00s)
        code_test.go:173:
                Error:          Target error should be in err chain:
                                expected: "error:  not found"
                                in chain: "error:  not found"

FAIL

エラー文が同一なのに通らなかったテストを通した際にわかったことをメモとしてまとめておきたいなと思います。

そもそもErrorIsメソッドとは

ErrorIsメソッドは、errorsパッケージのIsメソッドで行っているエラーチェーン内に特定のエラーが含まれているかを調べるメソッドです。

エラーチェーンとは

別パッケージ発生したエラーをラッピングして辿れるようにしたものです。

エラーを見た時に複数ファイルにおいて、このようなエラーが発生したとコンソール上に出てくると思います。

エラーを辿れるようにして、エラーがどのメソッドを通してどこが大元でエラーを吐いてるかを調べれるようにした仕組みをエラーチェーンと言います。

例えば、goのORMライブラリとして有名なGORMで用意されているNotFoundエラーがエラーチェーンに含まれてるかどうかという時にerrors.Isメソッドを使用できます。

require.ErrorIsでは、errors.Isのようにテストケース内で発生したエラーのエラーチェーンにおいて特定のエラーが含まれているかどうかができる、抽象メソッドです。

どうしてエラーが出てしまったのか

エラー文は同じだけど違うエラーが出ているということは、ErrorIsメソッドの話で気づけるようにエラーチェーンが違う可能性が考えられると思います。

ではどうしてエラーチェーンが異なってしまったかというと、Goにおけるフォーマット指定子が関係しています。

フォーマット指定子は下のような%で指定して、表示形式を決めているものです。

fmt.Sprintf("hello %s", w)

フォーマット指定子は%のあとに指定子で指定されている文字によって指定できるものが変わってきます。

一部例を出すと下のようになっています。

指定子
%v value
%t bool
%d 10進数(int)
%s 文字列(string)
%p ポインタ

今回のコードでは%sでstringを指定していると思います。

fmt.Errorf("error: %s", repository.ErrNotFound)

こうすることによってerror: not foundで一つのエラーになってしまいます。

今回はエラーチェーンとしてerror: not foundからgorm.ErrNotFoundのエラー文であるnot foundErrorIsメソッドで取り出されて欲しいのに、エラーチェーンが形成されず取り出すことができなかったので、テストが通らなかったというわけです。

エラーチェーンが形成されるようにするには、下のように実装します。

fmt.Errorf("mutual fund not found: %w", repository.ErrNotFound)

ドキュメントによると、%wを指定子に指定することでfmtで作成してくれるエラーにUnwrapメソッドを実装してくれます。

こうすることでエラーチェーンとして機能し、ErrorIsメソッドでエラーが含まれているかを調べるようにできるようになり、エラーが辿りやすくなります。

fmt.Errorfでエラー文を整形したいとなった時、テストでエラーが通らなくなった時はぜひ参考にしてください。

Go関連の記事

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?