假设您有以下内容
type Person interface {
GetFullName() string
PrintName()
}
type Banker struct {
FirstName string
LastName string
}
func (b Banker) GetFullName() string {
return fmt.Sprintf("%s %s", b.FirstName, b.LastName)
}
func (b Banker) PrintName() {
return log.Println(b.GetFullName())
}
如何从 PrintName 模拟 GetFullName?
注意,这只是一个使底层问题(接收器函数中使用的模拟接收器函数)更容易理解的示例
抛开你是否应该这样做的问题,你可以的一种方法是让你希望模拟的接收器函数围绕一个可以在测试中替换的函数变量进行包装:
var bankerGetFullName = func(Banker) string {
return fmt.Sprintf("%s %s", b.FirstName, b.LastName)
}
type Person interface {
GetFullName() string
PrintName()
}
type Banker struct {
FirstName string
LastName string
}
func (b Banker) GetFullName() string {
return bankerGetFullName(b)
}
func (b Banker) PrintName() {
return log.Println(b.GetFullName())
}
函数包装器未导出,因此不能被包外部的代码改变。
然后,假设您的测试与被测代码位于同一包中(有些人认为这本身就是不可取的),您的测试可以替换包装器实现以根据需要提供模拟:
// ARRANGE
og := bankerGetFullName
defer func() { bankerGetFullName = og }()
bankerGetFullName = func(Banker) string { return "mock result" }
sut := Banker{}
// ACT
result := sut.Print()
// ASSERT
... test the log output to verify that "mock result" was printed ...
正如我所说,这并不是建议您应该这样做,只是对如何可能或可以完成这一问题的直接回答。