我有一个简单的方法,它只检查参数是否为空,然后根据结构字段调用 2 个方法之一。
我将如何测试它?
func (cT *customType) someMethod(message string) {
if message == ""{
return
}
if cT.value == nil {
cT.doFunctionOne()
} else {
cT.doFunctionTwo()
}
}
Run Code Online (Sandbox Code Playgroud)
在 Javascript 中,我会创建一个监视对象doFunctionOne()并模拟该对象。
模拟Go也很有效,但是我该如何做“间谍”部分呢?
或者还有另一种惯用的方法来测试这种方法吗?
在 Go 中模拟对象的惯用方法是使其显式化。一个健康的界面应该是可自行测试的。所以如果我们有这样的东西:
type customType struct {
value int
}
func (c customType) doFunctionOne() {
fmt.Println("Method #1")
}
func (c customType) doFunctionTwo() {
fmt.Println("Method #2")
}
func (c customType) someMethod() {
if c.value <= 0 {
c.doFunctionOne()
} else {
c.doFunctionTwo()
}
}
Run Code Online (Sandbox Code Playgroud)
我们必须提供一种方法来显式地改变doFunctionOne和的实现doFunctionTwo。我们可以someMethod使用接口来概括行为:
type customType struct {
myValue int
}
func (c customType) doFunctionOne() {
fmt.Println("Method #1")
}
func (c customType) doFunctionTwo() {
fmt.Println("Method #2")
}
func (c customType) value() int {
return c.myValue
}
type Interface interface {
value() int
doFunctionOne()
doFunctionTwo()
}
func someMethod(i Interface) {
if i.value() <= 0 {
i.doFunctionOne()
} else {
i.doFunctionTwo()
}
}
type customTestingType struct {
t *testing.T
}
func (c customTestingType) doFunctionOne() {
c.t.Log("Working")
}
func (c customTestingType) doFunctionTwo() {
c.t.Error("Not working")
}
func (c customTestingType) value() int {
return 0
}
func TestInterface(t *testing.T) {
someMethod(customTestingType{t})
}
Run Code Online (Sandbox Code Playgroud)
当然会有更多的方法来提供这种行为,但这取决于您的类型的特定声明。作为示例,您可以查看 httptestpackage.json。也就是说,如果你真的想以这种方式模拟你的类型(非惯用),你可以进行一些不安全的猴子修补:
package main
import (
"fmt"
"reflect"
"github.com/bouk/monkey"
)
type customType struct {
myValue int
}
func (c customType) doFunctionOne() {
fmt.Println("Method #1")
}
func (c customType) doFunctionTwo() {
fmt.Println("Method #2")
}
func (c customType) someMethod() {
if c.myValue <= 0 {
c.doFunctionOne()
} else {
c.doFunctionTwo()
}
}
func main() {
c := customType{0}
monkey.PatchInstanceMethod(reflect.TypeOf(c), "doFunctionOne",
func(c customType) {
fmt.Println("Method #1, but patched")
})
monkey.PatchInstanceMethod(reflect.TypeOf(c), "doFunctionTwo",
func(c customType) {
fmt.Println("Method #2, but patched")
})
c.someMethod()
}
Run Code Online (Sandbox Code Playgroud)