Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
サンプル: Golangにおけるinterfaceをつかったテストで mock を書く技法
package main
import (
"context"
"fmt"
)
type GitHub interface {
CreateRelease(ctx context.Context, opt *Option) (string, error)
GetRelease(ctx context.Context, tag string) (string, error)
DeleteRelease(ctx context.Context, releaseID int) error
}
type GhRelease struct {
c GitHub
}
func (ghr *GhRelease) CreateNewRelease(ctx context.Context) (*Release, error) {
tag, err := ghr.c.CreateRelease(ctx, nil)
if err != nil {
return nil, fmt.Errorf("failed to create release: %v", err)
}
// check created release
if _, err := ghr.c.GetRelease(ctx, tag); err != nil {
return nil, fmt.Errorf("failed to get created release: %v", err)
}
// ...
return &Release{}, nil
}
type Option struct{}
type Release struct{}
package main
import (
"context"
"fmt"
"testing"
)
type fakeGitHub struct {
// インターフェース埋め込み
GitHub
FakeCreateRelease func(ctx context.Context, opt *Option) (string, error)
FakeGetRelease func(ctx context.Context, tag string) (string, error)
// 埋め込みを使うので,例えば DeleteRelease はまだテストしないので mock
// しない... いうことができる.
}
func (c *fakeGitHub) CreateRelease(ctx context.Context, opt *Option) (string, error) {
return c.FakeCreateRelease(ctx, opt)
}
func (c *fakeGitHub) GetRelease(ctx context.Context, tag string) (string, error) {
return c.FakeGetRelease(ctx, tag)
}
func TestGhRelease_CreateNewRelease(t *testing.T) {
fakeclient := &fakeGitHub{
FakeCreateRelease: func(ctx context.Context, opt *Option) (string, error) {
return "v1.0", nil
},
FakeGetRelease: func(ctx context.Context, tag string) (string, error) {
return "", fmt.Errorf("failed to get %v release!", tag)
},
}
ghr := &GhRelease{c: fakeclient}
release, err := ghr.CreateNewRelease(context.Background())
if err != nil {
t.Error(err)
// => failed to get created release: failed to get v1.0 release!
}
_ = release
// ...
}

参考になりました!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment