如何对使用另一个接收器函数的接收器函数进行单元测试

问题描述 投票:0回答:1

假设您有以下内容

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?

注意,这只是一个使底层问题(接收器函数中使用的模拟接收器函数)更容易理解的示例

unit-testing go
1个回答
0
投票

抛开你是否应该这样做的问题,你可以的一种方法是让你希望模拟的接收器函数围绕一个可以在测试中替换的函数变量进行包装:

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 ...

开发人员注意事项

正如我所说,这并不是建议您应该这样做,只是对如何可能可以完成这一问题的直接回答。

© www.soinside.com 2019 - 2024. All rights reserved.