0
0

More than 3 years have passed since last update.

xerrorsのerrorチェックの判定方法

Posted at

はじめに

開発でgoのテストを書いているときに
errorチェックのテストの書き方の使い分けについて話が出たのでひとつの考え方として残しておく。

また、errorのパッケージとしてgolang.org/x/xerrorsを使用している。

概要

単純にエラーの種類を判断するだけでいいのであれば、xerrors.Is()の結果をassert.True()に渡してチェックする。
Is()はbaseとなるerrorが両者で一致していればtrueになるので厳密なチェックにはならない。

具体的なエラーの内容までを見るのであれば、エラー文字列まで見ないといけないので
assert.EqualError()を使用する。

テスト対象のコード


package main

import (
    "golang.org/x/xerrors"
)

var baseDBErr = xerrors.New("db error")
var baseCacheErr = xerrors.New("cache error")

func main() {
    handler()
}

// テスト対象のfunc
func handler() error {

    if false {
        return err1()
    }
    if false {
        return err2()
    }
    if true {
        return err3()
    }
    return nil
}

// DB系のエラー
func err1() error {
    return xerrors.Errorf("t_user取得失敗: %w", baseDBErr)
}

// キャッシュ系のエラー
func err2() error {
    return xerrors.Errorf("マスターA取得失敗: %w", baseCacheErr)
}

// キャッシュ系のエラー
func err3() error {
    return xerrors.Errorf("マスターB取得失敗: %w", baseCacheErr)
}

テストコード


package main

import (
    "testing"

    "github.com/stretchr/testify/assert"
    "golang.org/x/xerrors"
)

func TestHandler(t *testing.T) {
    fail := map[string]struct {
        wantErr    error
        wantStrErr string
    }{
        "テストケースA": {
            wantErr:    baseCacheErr,
            wantStrErr: "マスターB取得失敗: cache error",
        },
    }

    t.Run("失敗", func(t *testing.T) {
        for tt, tc := range fail {
            t.Run(tt, func(t *testing.T) {

                err := handler()
                // キャッシュエラーかどうかは判断できるが、マスターAかBどちらの処理のエラーなのかがわからない
                assert.True(t, xerrors.Is(err, tc.wantErr))
                // 厳密なチェック(文字列をチェック)
                assert.EqualError(t, err, tc.wantStrErr)
            })
        }
    })
}
0
0
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
0
0