TL;DR

  • Mockio は、モックの構造体を事前に生成せずに使える Go のモックライブラリである。
  • 中で使う Go-dyno は、reflect で作った構造体のメソッドテーブルを書き換え、インタフェースを満たす構造体を実行時に作る。

内容

Mockio と Go-dyno

Mockio は、モックの構造体を事前に生成しなくてよいモックライブラリである。同じ開発者による Go-dyno に強く依存している。Go-dyno は、型パラメータに渡されたインタフェースを満たす構造体を動的に生成し、メソッドが呼ばれたときの振る舞いを引数で指定できる。

構造体を動的に生成する流れ

  1. インタフェースを満たす構造体を作る。
  2. 構造体のメソッドテーブルを書き換え、アセンブリで書いた処理に向き先を変える。
  3. メソッドから関数を呼び出す部分を確認する。
  4. 指定した振る舞いの関数を生成して実行させる。
  5. メソッドと関数で引数を共有する。

reflect の限界と回避策

リフレクションを使うと、reflect.StructOf で構造体を作り、指定したインタフェースを埋め込める。reflect.MakeFunc で関数も動的に作れる。しかし、レシーバの扱いや型安全性の問題があるので、メソッドは生成できない。

そこで、メソッドの中から関数を呼び出し、その関数の中身を自由に指定する。ただ、これも簡単ではない。どのインタフェースのどのメソッドを実行するかは実行時に決まるが、メソッドの側は関数にどんな引数を渡せばよいかを動的に切り替えられない。Go-dyno は、メモリ領域を直接操作してメソッド呼び出し時の引数を覗き見ることで、この問題を回避している。

キーワード

関連