LoginSignup
124
84

More than 5 years have passed since last update.

Golangのtestify/assert 使えそうな関数まとめ

Last updated at Posted at 2018-05-07

Introduction

最近Echoでサーバーを書く機会があった。
テストコードを書きたかった。
Echo Document Testingを見てみると

import (
    "net/http" //<- わかる
    "net/http/httptest" //<- わかる
    "strings" //<- わかる
    "testing" //<- 超わかる

    "github.com/labstack/echo" //<- わかる
    "github.com/stretchr/testify/assert" //<-なにこれ????
)

github.com/stretchr/testify/assertとか言うのかimportされていた

もう少し見てみると

func TestCreateUser(t *testing.T) {
    // Setup
    e := echo.New()
    req := httptest.NewRequest(echo.POST, "/", strings.NewReader(userJSON))
    req.Header.Set(echo.HeaderContentType, echo.MIMEApplicationJSON)
    rec := httptest.NewRecorder()
    c := e.NewContext(req, rec)
    h := &handler{mockDB}

    // Assertions
    if assert.NoError(t, h.createUser(c)) {
        assert.Equal(t, http.StatusCreated, rec.Code)
        assert.Equal(t, userJSON, rec.Body.String())
    }
}

「なるほど。 assertはRubyのvalidation的な立ち位置か。公式README読み行こ。」

「日本語版ないな」「和訳されたやつないかな」

Google[testify assert][Search]

「うんないな。書こう」

そんな経緯です、。ゆるく検証していきます

環境

go 1.9
assert 1.2.1

記載されている結果はすべて上記の環境により実行しております

比較

func ElementsMatch(リストの比較)

func ElementsMatch(t TestingT, listA, listB interface{}, msgAndArgs ...interface{}) (ok bool)

ElementMatchはlistA(array, slice...) とlistB(array, slice...)の要素が一致しているか判定します (順序は問わない)

assert.ElementMatch(t, [...]int{1,2}, [...]int{1, 2} ) //-> Success

assert.ElementMatch(t, [...]int{1,2}, [...]int{2, 1} ) //-> Success

assert.ElementMatch(t, [...]int{1,2}, [...]int{1} ) //-> Failed

assert.ElementMatch(t, [...]int{1,2}, [...]int{1, 3} ) //-> Failed


func Equal(比較検証)

func Equal(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool

2つのオブジェクトを比較します

assert.Equal(t, 123, 123) //-> Success
assert.Equal(t, 123, 321) //-> Failed

assert.Equal(t, "123", "123") //-> Success
assert.Equal(t, "123", "321") //-> Failed

assert.Equal(t, [...]int{1}, [...]int{1}) //-> Success
assert.Equal(t, [...]int{1}, [...]int{2}) //-> Failed

func Exactly(厳密な比較検証)

func Exactly(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool

厳密な比較検証します

assert.Exactly(t, int32(123), int64(123)) //-> Failed
assert.Exactly(t, int32(123), uint32(123)) //-> Failed
assert.Exactly(t, int32(123), 123) //-> Failed
assert.Exactly(t, "123", 123) //-> Failed

assert.Exactly(t, 123, 123) //-> Success

//------------------------------------
import "strconv"
assert.Exactly(t strconv.Itoa(123), "123") //-> Success

func JSONEq(JSONが同等であるか検証)

func JSONEq(t TestingT, expected string, actual string, msgAndArgs ...interface{}) bool

JSONは2つのJSONが同等であるか検証。こちらも順序は問わないみたいですね

assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"hello": "world", "foo": "bar"}`) //-> Success

assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world"}`) //-> Success

assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello": "world!"}`) //-> Failed

assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello!": "world"}`) //-> Failed

assert.JSONEq(t, `{"hello": "world", "foo": "bar"}`, `{"foo": "bar", "hello!": "world""}`) //-> Failed(Syntax Error)

func EqualError(Errorを比較)

func EqualError(t TestingT, theError error, errString string, msgAndArgs ...interface{}) bool

EqualErrorは、ある関数がエラーを返し(error)
それが提供されたエラー(String)と等しいことを検証します。

import "errors"

// errors.New() は Errorの作成
assert.EqualError(t, errors.New("HOGE"), "HOGE") //-> Success
assert.EqualError(t, errors.New("HOGE"), "FUGA") //-> Failed

func EqualValues

func EqualValues(t TestingT, expected, actual interface{}, msgAndArgs ...interface{}) bool

等しい値は、2つのオブジェクトが等しいか、同じ型に変換可能であり、等しいことを示します。

assert.EqualValues(t, uint32(123), int32(123)) //-> Success
assert.EqualValues(t, 123, int32(123)) //-> Success

assert.EqualValues(t, string(123), int32(123)) //-> Success

func IsType(同じ型であるか検証)

func IsType(t TestingT, expectedType interface{}, object interface{}, msgAndArgs ...interface{}) bool

2つの構造体が同じ型であることを検証します

type (
    User struct {
        ID   int
        Name string
        Age  int
        Have Have
    }
    Have struct {
        toy   bool
        drink bool
        bag   bool
    }
)
user1 := User{1, "Plata", 17, Have{true, false, true}}
user2 := User{2, "aznalo", 17, Have{false, false, true}}
have  := Have{true, false, true}
//----------------------------------------------------

assert.IsType(t, user1, user1) //-> Success

assert.IsType(t, user1, user2) //-> Success

assert.IsType(t, user1, new(User)) //-> Failed

assert.IsType(t, user1, new(Have)) //-> Failed

assert.IsType(t, user1, have) //-> Failed

Error*

func Error(Errorが返却されるか検証)

func Error(t TestingT, err error, msgAndArgs ...interface{}) bool

関数がErrorを返却することを検証

import "errors"

// errors.New() は Errorの作成
assert.Error(t, errors.New("HOGE")) //-> Success
assert.Error(t, nil) //-> Failed

func NoError(エラーが無いことを検証)

func NoError(t TestingT, err error, msgAndArgs ...interface{}) bool
import "errors"

assert.NoError(t, nil) //-> Success
assert.Error(t, errors.New("HOGE")) //-> Failed

func Fail(Fieldさせる)

Fieldを発生させます

func Fail(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool
assert.Fail(t, "HOGE") //->
/*--- FAIL: TestXxxx (0.03s)
        Error Trace:    xxx_test.go:xx
        Error:          HOGE
        Test:           TestXxxx
*/

func FailNow

func FailNow(t TestingT, failureMessage string, msgAndArgs ...interface{}) bool

func Failと差がわからない

assert.FailNow(t, "HOGE") //->
/*--- FAIL: TestXxxx (0.03s)
        Error Trace:    xxx_test.go:xx
        Error:          HOGE
        Test:           TestXxxx
*/

func FileExists(ファイルのパスが存在するか検証)

func FileExists(t TestingT, path string, msgAndArgs ...interface{}) bool

指定されたパスにファイルが存在するかどうかをチェックします。またディレクトリを指定した場合は失敗します

assert.FileExists(t, "/go/src/app/controllers/API/main.go") //-> Success

assert.FileExists(t, "/go/src/app/controllers/API") //-> Failed

assert.FileExists(t, "/go/src/app/controllers/API/bash") //-> Failed

存在を検証

func Empty(値が空か検証)

func Empty(t TestingT, object interface{}, msgAndArgs ...interface{}) bool

Objectが空であることを判定します。
nil""false0、またはlen == 0のスライスは検証は成功します

assert.Empty(t, nil) //-> Success

assert.Empty(t, 0) //-> Success
assert.Empty(t, 1) //-> Failed

assert.Empty(t, "") //-> Success
assert.Empty(t, "Qiita") //-> Failed

assert.Empty(t, [...]int{}) //-> Success
assert.Empty(t, [...]int{1}) //-> Failed
//--------------------------------------
type User struct {
  Name string
}
test := User{}
assert.Empty(t, test) //-> Success

func False(検証対象がFalseか検証*)

func False(t TestingT, value bool, msgAndArgs ...interface{}) bool
assert.False(t, false) //-> Success
assert.False(t, true) //-> Failed

また同じような挙動の関数に func Truefunc Nillがあります

func Len(リストの要素数の検証)

func Len(t TestingT, object interface{}, length int, msgAndArgs ...interface{}) bool
assert.Len(t, [...]int{1,2,3}, 3) //-> Success
assert.Len(t, [...]int{1,2,3}, 4) //-> Failed

assert.Len(t, [...]string{"1","2","3"}, 3) //-> Success
assert.Len(t, [...]string{"1","2","3"}, 4) //-> Failed

func Contains(含まれることを検証)

func Contains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool
assert.NotContains(t, "Hello World", "Earth") //-> Failed
assert.NotContains(t, [...]string{"Hello", "World"}, "Earth")//-> Failed
assert.NotContains(t, "Hello", "World")//-> Failed

assert.NotContains(t, "HelloWorld", "World")//-> Success
assert.NotContains(t, "Hello World", "World")//-> Success
assert.NotContains(t, [...]string{"Hello", "World"}, "World")//-> Success

func NotContains(含まれないことを検証)

func NotContains(t TestingT, s, contains interface{}, msgAndArgs ...interface{}) bool

NotContainsは、指定された文字列、list(array、slice ...)またはmapに、指定された部分文字列または要素が含まれていないことを検証

assert.NotContains(t, "Hello World", "Earth") //-> Success
assert.NotContains(t, [...]string{"Hello", "World"}, "Earth")//-> Success
assert.NotContains(t, "Hello", "World")//-> Success

assert.NotContains(t, "HelloWorld", "World")//-> Failed
assert.NotContains(t, "Hello World", "World")//-> Failed
assert.NotContains(t, [...]string{"Hello", "World"}, "World")//-> Failed

やってみて

Documentに書いてある関数多すぎて全部目を通すのにやっとった

124
84
1

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
124
84