2
1

More than 3 years have passed since last update.

しばらく使わなかった言語はすぐ忘れる

Last updated at Posted at 2020-01-08

昨年の2019年の6月頃触っていたgolangで素晴らしいモックの作成方法を学んだのに、
半年たってモックを作成しようとしたらテストの書き方含め「どうやるんだっけ...?」と忘れてしまいました。

エビングハウスの忘却曲線によると学んだことは1ヶ月後も経てばほぼ忘れてると同義らしいので、
忘れた事を悲観するのではなく、アウトプットを含めた復習をすることで記憶を強化したいと思います。

github.comのソースはこちら

サンプルプログラム

例えばこんなプログラムがあったとします。

layer1.go

package exPackage

type exStruct1 struct {
    Layer2 Layer2Interface
}

type Layer1Interface interface {
    Receiver() bool
}

func NewLayer1(Layer2 Layer2Interface) Layer1Interface {
    return &exStruct1{Layer2}
}

func (e *exStruct1) Receiver() bool {
    if e.Layer2.Get() != 1 {
        return false
    }

    if e.Layer2.Put(2) == false {
        return false
    }

    if e.Layer2.Delete(3) == false {
        return false
    }

    return true
}

テストを書く時にNewLayer1メソッドに対して渡すLayer2はGet,Put,Deleteのメソッドを持つ事とします。

layer2.go

package exPackage

type Layer2Interface interface {
    Get() int
    Put(param int) bool
    Delete(key int) bool
}

レイヤー2のモックを作成してテストをしたいのでモックを作成します。

Mockの作成

Get,Put,Deleteのメソッドの返却はすべてFake XXXX というメソッドに丸投げします。

package exMock

import "golang-public/test-benchMark/exMock/exPackage"

type Layer2 struct {
    exPackage.Layer2Interface

    FakeGet    func() int
    FakePut    func(param int) bool
    FakeDelete func(key int) bool
}

func (l Layer2) Get() int {
    return l.FakeGet()
}

func (l Layer2) Put(param int) bool {
    return l.FakePut(param)
}

func (l Layer2) Delete(key int) bool {
    return l.FakeDelete(key)
}

テストの作成

こうすることで、素晴らしい事にモックの内容をテスト単位で書き換える事が可能になる。

func TestReceiver(t *testing.T) {
    tests := []struct {
        name string
        f    func(*testing.T)
    }{
        {
            "Getでfalseが返却される",
            func(t *testing.T) {
                layer2Mock := exMock.Layer2{
                    FakeGet: func() int {
                        return 2
                    },
                }

                layer1 := exPackage.NewLayer1(layer2Mock)

                assert.Equal(t, layer1.Receiver(), false)
            },
        },
        {
            "Putでfalseが返却される",
            func(t *testing.T) {
                layer2Mock := exMock.Layer2{
                    FakeGet: func() int {
                        return 1
                    },
                    FakePut: func(param int) bool {
                        return false
                    },
                }

                layer1 := exPackage.NewLayer1(layer2Mock)

                assert.Equal(t, layer1.Receiver(), false)
            },
        },
        {
            "Deleteでfalseが返却される",
            func(t *testing.T) {
                layer2Mock := exMock.Layer2{
                    FakeGet: func() int {
                        return 1
                    },
                    FakePut: func(param int) bool {
                        return true
                    },
                    FakeDelete: func(key int) bool {
                        return false
                    },
                }

                layer1 := exPackage.NewLayer1(layer2Mock)

                assert.Equal(t, layer1.Receiver(), false)
            },
        },
        {
            "すべてが成功してtrueが返却される",
            func(t *testing.T) {
                layer2Mock := exMock.Layer2{
                    FakeGet: func() int {
                        return 1
                    },
                    FakePut: func(param int) bool {
                        return true
                    },
                    FakeDelete: func(key int) bool {
                        return true
                    },
                }

                layer1 := exPackage.NewLayer1(layer2Mock)

                assert.Equal(t, layer1.Receiver(), true)
            },
        },
    }

    for _, tt := range tests {
        t.Run(tt.name, tt.f)
    }
}

参考

Golangにおけるinterfaceをつかったテストで Mock を書く技法

2
1
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
1