🙌

mockioを使ってみた

に公開

タイトルどおり、mockioを使ってみただけの記事です。

最近、偶然Xで以下のツイートを見てmockioの存在を知りました。

公式

公式ドキュメントとgithubは以下のとおり。

GitHub GistのページURLを指定してください

https://ovechkin-dm.github.io/mockio/latest/

GitHub GistのページURLを指定してください

https://github.com/ovechkin-dm/mockio/

Javaのmockitoにインスパイアされたモックライブラリ、とのこと。

GitHub GistのページURLを指定してください

https://site.mockito.org/

お試し

お試し対象のコード

まずはちょっとしたテスト対象となるコードを作成します。
すごくシンプルな処理で単純にユーザー名を返却するだけの処理になります。

ちょっとだけ階層化していて、usecase -> repositoryのような呼び出し順序にしています。

main.go

package main

import (
	"fmt"
	"test1/repository"
	"test1/usecase"
)

func main() {
	userRepo := repository.NewUserRepository()
	usecase := usecase.NewGetUserUsecase(userRepo)
	username := usecase.Execute()
	fmt.Println(username) // UserName
}

usecase/user.go

package repository

type UserRepository interface {
	GetUser() string
}

type userRepository struct{}

func NewUserRepository() UserRepository {
	return &userRepository{}
}

func (r *userRepository) GetUser() string {
	return "UserName"
}

repository/user.go

package repository

type UserRepository interface {
	GetUser() string
}

type userRepository struct{}

func NewUserRepository() UserRepository {
	return &userRepository{}
}

func (r *userRepository) GetUser() string {
	return "UserName"
}

ユニットテスト

usecaseに対してユニットテストを記述し、この中で今回のmockioを試してみようと思います。

usecase/user_test.go

package usecase_test

import (
	"test1/repository"
	"test1/usecase"
	"testing"

	"github.com/ovechkin-dm/mockio/v2/mock"
)

func TestGetUserUsecase_Execute(t *testing.T) {
	ctrl := mock.NewMockController(t)
	m := mock.Mock[repository.UserRepository](ctrl)
	mock.WhenSingle(m.GetUser()).ThenReturn("TestUserName")

	type args struct {
		userRepo repository.UserRepository
	}
	tests := []struct {
		name string
		args args
		want string
	}{
		{
			name: "test",
			args: args{
				userRepo: m,
			},
			want: "TestUserName",
		},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			u := usecase.NewGetUserUsecase(tt.args.userRepo)
			if got := u.Execute(); got != tt.want {
				t.Errorf("GetUserUsecase.Execute() = %v, want %v", got, tt.want)
			}
		})
	}
}

ポイントはテストコードの最初でモックを作成している箇所だと思います。

  • NewMockControllerでmock用のコントローラを作成
  • モック対象のrepository.UserRepositoryのモックを作成します。
  • モックしたい関数を指定、さらに呼び出された時の返却を指定します。

感想

gomockなどに慣れていれば、すぐに理解できると思います。
内部実装をちょっとだけ見てみたのですが、gomockとは違い、genericsをうまく活用してコード生成せずともモックできるようにしてているようでした。

本当に少し触っただけではありますが、使い心地も良さそうなので、もう少し調査した上で仕事にも活用していこうと思いました。

Discussion