今回は、テストコードを簡単にするためにTestifyを使いますが、Testifyの機能で、モック化するわけではないので、Testifyを導入しなくてもモック化の実現が可能です。
今回利用する技術
- 言語:GO
- モック化する外部ライブラリ:Agouti Seleniumみたいなライブラリ
- テストライブラリ:Testify assertなどの検証関数を利用するため
実況開始
まず初めは、GOのプロジェクトの初期化してみる
go mod init go-testify-mock
正直、go modのことをが詳しくないから、npm init -y
と同じ感覚として、やっていいのかわからない....
Testifyのインストール
go get github.com/stretchr/testify
Agoutiのインストール
go get github.com/sclevine/agouti
ライブラリの公式が、メンテナンスしないことを発表して、3年立つらしい...
モック化するために、外部ライブラリの構造体のクロージャーのラッパー関数を作成する
GOの標準のテスト機能やTestifyでは、Jestのfn()
やspyOn()
のように、外部ライブラリを直接モック化できない。
そのため、モック化するために、構造体のプロパティにラッパー関数として、クロージャーを定義し、関数の代入をするための初期化関数を作成する。
めんどくさい、直接モック化させてくよぉ......。
ていうか、これ略したら、DIだよな......。
import (
"github.com/sclevine/agouti"
)
type Scraping struct {
// スクレイピングするページのタイトルの取得
GetPageTitle func(url string) (string, error)
}
/*
初期化処理
*/
func (scraping *Scraping) Init() {
// エラー処理は、めんどくさいので飛ばします。
scraping.GetPageTitle = func(url string) (string, error) {
options := agouti.ChromeOptions(
"args", []string{
"--headless",
"--disable-gpu",
})
driver := agouti.ChromeDriver(options)
defer driver.Stop()
driver.Start()
page, _ := driver.NewPage()
page.Navigate(url)
return page.Title()
}
}
テストコードを作成する
mockInit()
で、GetPageTitle
の中身を書き換えます。
やり方が、脳筋に思えてしまう...
package test
import (
"go-testify-mock/src/modules"
"testing"
"github.com/stretchr/testify/assert"
)
func mockInit() *modules.Scraping {
scraping := &modules.Scraping{}
scraping.GetPageTitle = func(url string) (string, error) {
return "title", nil
}
return scraping
}
func TestGetPageTitle(t *testing.T) {
title, error := mockInit().GetPageTitle("url")
if assert.NoError(t, error) {
assert.Equal(t, "title", title)
}
}