LoginSignup
2
3

More than 5 years have passed since last update.

グローバル変数を使ったGo言語のテクニック

Last updated at Posted at 2018-08-06

Goでランダム関数を使う時にグローバル変数に入れる事でスタブテストがしやすくなる

以下の事に困ってる人に役に立つ内容になっている

・ランダムな値のスタブのテストが出来ない。
・日付を扱ったスタブのテストが出来ない
・引数に上記のような値を入れて解決してるが微妙だと思ってる人

結論

※結論から先に記載しておく。そこに行きついた背景などは下に書いておく。
ランダム関数をグローバル変数に入れて、使用する箇所で呼び出せばよい。
こんな感じ↓

// hoge.go
// グローバル変数に関数をぶち込む
var getRandNum = func(num uint) uint {
    rand.Seed(time.Now().UnixNano())
    return uint(rand.Intn(int(num)) + 1)
}

func hoge() string {
    var num uint = 7
    randNum := getRandNum(num)
    if randNum%2 == 0 {
        return "偶数"
    }
    if randNum%2 == 1 {
        return "奇数"
    }
    return "異常"
}
//hoge_test.go
func TestName(t *testing.T) {
    type testSet struct {
        num      uint
        expected string
    }

    testCase := []testSet{
        {13, "奇数"},
        {20, "偶数"},
        {15, "奇数"},
    }

    for _, test := range testCase {
        // グローバル変数に定数値を挿入
        getRandNum = func(num uint) uint { return test.num }
        actual := hoge()
        if actual != test.expected {
            t.Errorf("got %v\nwant %v", actual, test.expected)
        }
    }
}

困ったこと

こんな感じのソースコードを書いていて、いざテストを書こうとしたときに書けなかった。

func hoge() string {
    var num uint = 7

    rand.Seed(time.Now().UnixNano())
    randNum := uint(rand.Intn(int(num)) + 1)

    if randNum%2 == 0 {
        return "偶数"
    }
    if randNum%2 == 1 {
        return "奇数"
    }
    return "異常"
}

理由は、ランダムな値をスタブすることが出来なかった。
解決策は他にもあった。
例えばこんな感じに引数にランダム値を取らせル方法

func hoge() string {
    var num uint = 7

    rand.Seed(time.Now().UnixNano())
    randNum := uint(rand.Intn(int(num)) + 1)

    return huga(randNum)
}

func huga(num uint) string {

    if num%2 == 0 {
        return "偶数"
    }
    if num%2 == 1 {
        return "奇数"
    }
    return "異常"
}

これが一般的な解決策にも思えるが、これだと呼び出し側がランダムな値を渡すことを知ってしまうし、
他のケースだと引数が多い場合もあると思う。
なのでスマートじゃない。ってことでグローバル変数を使って処理を書いた。
※ グローバル変数を小文字スタートで定義したらパッケージ内からしかさせないので、外にそんなに影響がないと思ってる。

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3