unit-testing - 如何只模拟接口(interface)的一种方法

标签 unit-testing go mocking testify gomock

我正在努力理解 Go 中的模拟(正在寻找与 Mockito.spy 相关的东西,相当于 Go 中的 java)。

假设我在 Go 中有一个接口(interface),其中包含 5 个方法。但是我要测试的这段代码只引用了两种方法。现在我如何在不实现所有方法的情况下模拟这种依赖关系,即我在源代码中的实际实现实现了接口(interface)的 5 种方法,但是有没有办法避免在测试文件中实现 5 种方法的虚拟接口(interface)实现。以下是我目前的做法,实现 5 个方法是可以管理的,但是如果接口(interface)有 20 个方法,模拟实现测试文件中的所有方法会变得乏味。

示例:

handler.go 中的源代码:

type Client struct {}
type ClientStore interface {
  func(c *Client) methodOne() error {// some implementation}
  func(c *Client) methodTwo() error {// some implementation}
  func(c *Client) methodThree() error {// some implementation}
  func(c *Client) methodFour() error {// some implementation}
  func(c *Client) methodFive() error {// some implementation}
}

api.go 中的源代码:

 func processFeed(c Client) error {
     err := c.methodOne()
     if(err != null) {
      return err
    }
     err1 := c.methodTwo()
     if(err1 != null) {
      return err1
    }
 }

测试类代码:

import "testify/mock"

func TestFeed(t *testing.T){
   mockClient := &MockClient{}
   err := processFeed(mockClient)
   assert.NotNil(t , err)
 
}

type MockClient struct {
  mock.Mock
}

  func(c *MockClient ) methodOne() error {fmt.Printf("methodOne");nil}
  func(c *MockClient ) methodTwo() error {return errors.New("mocked error")}
  func(c *MockClient ) methodThree() error {fmt.Printf("methodThree");nil}
  func(c *MockClient ) methodFour() error {fmt.Printf("methodFour");nil}
  func(c *MockClient ) methodFive() error {fmt.Printf("methodFive");nil}


问题:

有没有办法只模拟我在上述情况下只需要 methodOne() 和 methodTwo() 方法而不用担心测试中的剩余方法?如果有其他选择,您能否提出建议?谢谢

最佳答案

首先,如果您的接口(interface)有 5 个方法,而您只使用一个方法,那么您的接口(interface)太大了。使用较小的界面。

type BigInterface interface {
    Thing1()
    Thing2()
    ThingN()
}

type SmallInterface interface {
    Thing1()
}

func MyFunc(i SmallInterface) { ... }

另一种选择是通过嵌入完整接口(interface)来创建完整接口(interface)的完整实现。如果您尝试访问其他方法之一,这将引起 panic ,但如果您小心的话,它将用于测试。 (但请不要在生产代码中这样做!)

type BigInterface interface {
    Thing1()
    Thing2()
    ThingN()
}

type myImplementation struct {
    BigInterface
}

func (i *myImplementation) Thing1() { ... }

现在 myImplementation 满足 BigInterface 接口(interface),因为它包含 BigInterface 的嵌入式实例。如果您从未将该嵌入式实例设置为任何内容,那么调用这些方法将会出现困惑,但您仍然可以定义 Thing1 来执行您想要的测试。

关于unit-testing - 如何只模拟接口(interface)的一种方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56907401/

相关文章:

java - 应该如何设计执行 CRUD 操作的 Bean 的单元测试?

android - org.mockito.exceptions.misusing.NotAMockException : Argument should be a mock, 但是是 : class java. lang.Class for Andriod SSLContext.getInstance() 方法

ruby-on-rails - 测试 : how to focus on behavior instead of implementation without losing speed?

unit-testing - Jest - 'child_process' 包中的模拟函数

go - 在实现相同接口(interface)的多个结构上定义方法

java - Clojure/Java 中的 Goroutine 等价物

python - 测试实例中的方法是否已在 mock 中调用

ios - 在单元测试中,验证使用参数 NSData 调用的函数(其中包含 NSString)

c# - 最小起订量测试无效方法

debugging - 如何在VSCode Debug模式下显示整个值