post Image
goでmockを使ったテストをする

モックを使ったテストって?

テストのために本物のオブジェクトを使わず、テスト用に差し替える手法です。

モックを用いたテスト自体、否定派・賛成派あるのでいろいろ意見はありますが
階層型のアーキテクチャを選定していると、一番下のレイヤまで気を配らないと
上位層のテストがかけないのはしんどいですしよね。

例えば

  • 他社API処理

通信コケてCIガー、実行時間ガー

  • データベースがらみ

並列実行すると、コケるワー、実行時間ガー

テストの障害が増えると、テストを書かなくなりますし、メンテナンスも大変に
なっていくので使える所は使った方が良いのかな、と。

一番ストレートなやり方 (例)

goの記事というか基本的なDIの活用例っぽいですが…

  • 基本的にinterfaceに依存する。
  • DI(Dependency Injection)を活用する。

  • テスト対象のサンプルコード


package main

import (
    "errors"
)

type APIClient interface {
    Call(string) (map[string]string, error)
}

type UserRegister struct {
    client APIClient // interfaceに依存させる。
}

type User struct {
    Name string
}

// 引数に受け取ったnameを元に別APIでuserを登録する
func (u *UserRegister) Register(name string) (*User, error) {
    apiResult, err := u.client.Call(name)
    if err != nil {
        return nil, err
    }
    resultName, exist := apiResult["name"]
    if !exist {
        return nil, errors.New("apiResult must have name")
    }

    return &User{resultName}, nil
}
  • テストコード

package main

import (
    "testing"
)

// mockする構造体を定義する
type APIClientMock struct {
}

// APIClientInterfaceを満たすようにモックを実装する
func (a *APIClientMock) Call(name string) (map[string]string, error) {
    return map[string]string{"name": name}, nil
}

func TestRegister(t *testing.T) {
    // Mockを外部注入する
    target := &UserRegister{&APIClientMock{}}
    expected := "Mike"
    user, err := target.Register(expected)
    if err != nil {
        t.Fatalf("Register error: %v", err)
    }
    actual := user.Name
    if actual != expected {
        t.Fatalf("name Must be %s", expected)
    }
}

goには継承の概念がない代わりにembedで実装の再利用を可能に
していますが、型判定は通りません。
オブジェクト指向っぽく書く場合はinterfaceを使う方が良いですね。
(goに限らず…な所もありますが)

便利ライブラリ

上記の例では省きましたがより厳密にテストをするのであれば、
UserRegisterの責務である、APIClient.Call()の呼び出しの担保されたかまで考慮しないといけないので、
もう少し実装をかけないといけなくて、それはそれで面倒ですよね。
毎回作るのも面倒臭いし。

他の言語でも大概その手のライブラリはありますし、goにも勿論あります。

こちらのライブラリなら以下のような使い心地で簡単にできます。

//trueで呼ばれたら1を返す
mock.EXPECT().Method(true).Return(1)
// 初回は1,"first"で呼ばれることを保証
firstCall := mock.EXPECT().SomeMethod(1, "first")
// 1で呼ばれた後で2,"second"で呼ばれることを保証
secondCall := mock.EXPECT().SomeMethod(2, "second").After(firstCall)
// 2で呼ばれた後に3,"third"で呼ばれることを保証
mockObj.EXPECT().SomeMethod(3, "third").After(secondCall)

mockgenでmockのgenerateも出来るのでとても便利です 🙂

関連


『 Go 』Article List
Category List

Eye Catch Image
Read More

Androidに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

AWSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Bitcoinに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

CentOSに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

dockerに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

GitHubに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Goに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Javaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

JavaScriptに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Laravelに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Pythonに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Rubyに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Scalaに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Swiftに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Unityに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Vue.jsに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

Wordpressに関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。

Eye Catch Image
Read More

機械学習に関する現役のエンジニアのノウハウ・トレンドのトピックなど技術的な情報を提供しています。コード・プログラムの丁寧な解説をはじめ、初心者にもわかりやすいように写真や動画を多く使用しています。