fmt.Errorf("%s is foo、got%s"、bar、baz)のようなエラーを作成している場合、文字列値を比較せずに同等性をテストする方法はありますか?
このアイデアを探索するのに役立つ関数を作りましょう。
// DumbGetter will get the string body of url if it gets a 200funcDumbGetter(urlstring)(string,error){ res, err := http.Get(url)if err !=nil{return"", fmt.Errorf("problem fetching from %s, %v", url, err)}if res.StatusCode != http.StatusOK {return"", fmt.Errorf("did not get 200 from %s, got %d", url, res.StatusCode)}defer res.Body.Close() body, _ := ioutil.ReadAll(res.Body)// ignoring err for brevityreturnstring(body),nil}
t.Run("when you don't get a 200 you get a status error", func(t *testing.T) {
svr := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusTeapot)
}))
defer svr.Close()
_, err := DumbGetter(svr.URL)
if err == nil {
t.Fatal("expected an error")
}
want := fmt.Sprintf("did not get 200 from %s, got %d", svr.URL, http.StatusTeapot)
got := err.Error()
if got != want {
t.Errorf(`got "%v", want "%v"`, got, want)
}
})
type BadStatusError struct {
URL string
Status int
}
t.Run("when you don't get a 200 you get a status error", func(t *testing.T) {
svr := httptest.NewServer(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) {
res.WriteHeader(http.StatusTeapot)
}))
defer svr.Close()
_, err := DumbGetter(svr.URL)
if err == nil {
t.Fatal("expected an error")
}
got, isStatusErr := err.(BadStatusError)
if !isStatusErr {
t.Fatalf("was not a BadStatusError, got %T", err)
}
want := BadStatusError{URL: svr.URL, Status: http.StatusTeapot}
if got != want {
t.Errorf("got %v, want %v", got, want)
}
})
func (b BadStatusError) Error() string {
return fmt.Sprintf("did not get 200 from %s, got %d", b.URL, b.Status)
}
--- FAIL: TestDumbGetter (0.00s)
--- FAIL: TestDumbGetter/when_you_dont_get_a_200_you_get_a_status_error (0.00s)
error-types_test.go:56: was not a BadStatusError, got *errors.errorString