web-dev-qa-db-ja.com

Goエラーを単体テストする方法

errorの戻り値の型を持つ関数を単体テストする場合、このエラーを適切に単体テストする方法を考えていました。エラーがnilかnilでないかを確認するだけですか?または、エラー文字列が期待される文字列と一致することを確認する必要がありますか?

15
GabeMeister

ほとんどの場合、エラーがnilでないかどうかを確認できます。

どうしても必要な場合以外は、エラー文字列をチェックしないことをお勧めします。通常、エラー文字列は人間が使用するためのものであると考えています。

エラーの詳細が必要な場合は、カスタムエラータイプを使用することをお勧めします。次に、err。(type)を切り替えて、それが期待するタイプかどうかを確認できます。さらに詳細が必要な場合は、カスタムエラータイプに値を含めて、テストでチェックできます。

Goのエラーは、Error() stringメソッドを持つ型のインターフェースにすぎないため、自分で実装するのは簡単です。 https://blog.golang.org/error-handling-and-go

4
Omar

はい、エラーを返す関数をテストし、エラーメッセージが一致するかどうかを確認します。しかし、それを確認するか、単にエラーを確認するかはnilではありません。

次のような関数があるとします。

_func returnSomeErr(input int)error{
    if input > 0{
        return nil
    }
    return errors.New("this is error message")
}
_

あなたはこのようなエラーメッセージをユニットテストすることができます:

_// testing tot get error message
func TestReturnSomeErr(t *testing.T){
   Expected := "this is error message"
   actual := returnSomeErr(-1)

   if actual.Error() != Expected{
        t.Errorf("Error actual = %v, and Expected = %v.", actual, test.Expected)
   }
}
_

文字列と比較できるように、.Error()関数を使用してエラーメッセージを取得していることに注意してください。入力データが_> 0_の場合にエラーがないかどうかをテストする別のテストを作成できます。

2
Gujarat Santana

私はよくこの単純な関数を使ってエラーをチェックします:

_// ErrorContains checks if the error message in out contains the text in
// want.
//
// This is safe when out is nil. Use an empty string for want if you want to
// test that err is nil.
func ErrorContains(out error, want string) bool {
    if out == nil {
        return want == ""
    }
    if want == "" {
        return false
    }
    return strings.Contains(out.Error(), want)
}
_

使用例:

_if !ErrorContains(err, "unexpected banana") {
    t.Errorf("unexpected error: %v", err)
}

if !ErrorContains(err, "") {
    t.Errorf("unexpected error: %v", err)
}
_

これは、次のようなことができるので、テーブル駆動テストで特に便利です。

_tests := struct{
    want    string
    wantErr string
}{
    {
        "some output",
        "",  // No error expected
    },
    {
        "",
        "out of coconuts",
    }
}
_

nilerrors.New()などをいじるのを避けます。

完全なエラーをチェックする代わりに、string.Contains()を使用しています。これが大体私が期待しているエラーであるかどうかを知りたいだけです(完全に無関係なエラーではありません)。エラーメッセージ全体を確認することはほとんどありませんが、代わりにキーワードを使用します(「予期しない終了」、「不十分」など)。


この関数は github.com/teamwork/test パッケージの一部です(私はその主な作成者です)が、この関数のみを使用し、他の関数を使用しない場合は、コピーして貼り付けるだけです。そのパッケージで。

1
Martin Tournoij