2020/03/26

[golang]本体無しでテストをしたい (3)

前回、golangで埋め込みというものを使うと継承っぽいことができることが分かった。

では、それをどうテストやmockに応用すると良いのだろうか?

【Go言語】埋め込みでinterfaceを簡単に満たす - Eureka Engineering - Medium
https://medium.com/eureka-engineering/golang-embedded-ac43201cf772

 

テストしたいのは、UserInterfaceを引数に持つIsTestTarget()関数。
何を困っているかというと、この関数内でさらに関数を呼び出しているところだ。
u.Age()の戻り値を26とか25にして、trueだったりfalseだったりになることを確認したいのだが、u.Age()の戻り値をどうやって変更させるか。。。

 

というわけで、ここではUserInterfaceを埋め込んだtestUserという構造体を作り、testUserをreceiverとするAge()関数を作ってしまう。
そうすると、testUserは本体の実装からは切り離されるし、u.Age()は好きな値を返せるようになるし、めでたしめでたし。

「これって、UserInterfaceのテストじゃなくて、testUserのテストになるんじゃないの?」と気がしたが、そもそもIsTestTarget()が実行できれば良いだけなので、その引数にそこまでこだわる必要はあるまい。


では、話の始まりに戻ろう。

testingだけで完結するmockを作る #Golang - Qiita
https://qiita.com/maitaketurn/items/2618e9ecd68852a0a83b

 

テスト対象の構造体TaskControllerはinterfaceのTaskInterfaceを埋め込んでいて、テスト側のmockTaskControllerもTaskInterfaceを埋め込んで、それをreceiverに持つcreateTaskとupdateTaskと同じsignatureの関数がある。

それとは別に、mockCreateTaskとmockUpdateTaskというメンバがあるが、これは関数ポインタみたいなものだろう。
継承したような形で実装したcreateTask()とupdateTask()は、このmockCreateTaskとmockUpdateTaskを呼び出すだけだ。
だから、実際に呼ぶ前にmockCreateTaskとmockUpdateTaskには本体のアドレスを教えてやらねばならぬ。

 

あれに近いか。
fffでfakeを設定するやつだ。例えが分かりづらくて済まんね。
ともかく、テストごとに返したい値が変わるから可変値というやり方もあるけど、ここでは関数ごと差し替えられるようにした、と。


こういうのは、実装し続けていたらわかるようになるだろう。
少なくとも、go.modよりも理解はしやすいだろう。

次回は、自分のテストに埋め込みを使ってやってみる。

0 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。