2020/03/25

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

テストでmockを使う方法を調べているつもりだったが、いつの間にか埋め込みというものを調べていた。
まあよくあることだ。

 

そもそも、埋め込みのパターンの記事から読み始めてはいかんな。
埋め込みとは何か、から見なくては。

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

大ざっぱな理解だろうが、継承っぽいことができる、ということでいいのかな。
vtblをコピーしてアドレスが同じところを指しているだけなので、定義すればオーバーライドしてそのメソッドだけは別のものを指定できる、と。
interfaceを埋め込んだ場合はどこも指していないので、定義すれば呼び出せるし、定義しなければnilか何かになっていて呼べない。

 

body.go

01: package body
02: 
03: type BodyInterface interface {
04:     Go() string
05:     GoGo() string
06: }
07: 
08: type BodyStruct struct {
09:     BodyInterface
10: }
11: 
12: func (body *BodyStruct) Go() string {
13:     return "Go"
14: }
15: 
16: func (body *BodyStruct) GoGo() string {
17:     return "GoGo"
18: }

 

mummy.go

01: package body
02: 
03: type MummyStruct struct {
04:     BodyStruct
05: }
06: 
07: func (body *MummyStruct) GoGo() string {
08:     return "MuMu"
09: }

 

main.go

01: package main
02: 
03: import (
04:     "ex6/body"
05:     "fmt"
06: )
07: 
08: func main() {
09:     var body0 body.BodyStruct
10:     fmt.Printf("%s\n", body0.Go())
11:     fmt.Printf("%s\n", body0.GoGo())
12: 
13:     var body body.MummyStruct
14:     fmt.Printf("%s\n", body.Go())
15:     fmt.Printf("%s\n", body.GoGo())
16: }

$ go run ex6/main
Go
GoGo
Go
MuMu

 

MummyStructをreceiverに持つGo()は実装していないのだが、BodyStructのGo()が呼び出せている。
予想通りだ。

 

では、こうしたらどうなる?

 

mummy.go

01: package body
02: 
03: type MummyStruct struct {
04:     BodyInterface
05: }
06: 
07: func (body *MummyStruct) GoGo() string {
08:     return "MuMu"
09: }

 

main.go

01: package main
02: 
03: import (
04:     "ex6/body"
05:     "fmt"
06: )
07: 
08: func main() {
09:     var body0 body.BodyStruct
10:     fmt.Printf("%s\n", body0.Go())
11:     fmt.Printf("%s\n", body0.GoGo())
12: 
13:     var body body.MummyStruct
14:     fmt.Printf("%s\n", body.GoGo())
15:     fmt.Printf("%s\n", body.Go())
16: }

継承っぽいことをしている箇所を、BodyStructではなくBodyInterfaceにしたのだ。
まあ、結果の予想が付くので、Printfするところもbody.GoGo()を先に呼び出すようにした。

$ go run ex6/main
Go
GoGo
MuMu
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x48ea85]

goroutine 1 [running]:
main.main()
        /home/xxx/go/src/ex6/main/main.go:15 +0x1e5
exit status 2

 

定義したMummyStructのGoGo()は呼び出しできているが、定義していないGo()を呼び出すとpanicが発生している。
予想通りですな。

 

では、次回はこれをどうテストに応用できるのか、だ。

0 件のコメント:

コメントを投稿

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

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