登录
首页 >  Golang >  Go问答

增加Go库方法的可测试性的方法

来源:stackoverflow

时间:2024-03-12 23:27:24 419浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《增加Go库方法的可测试性的方法》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

问题内容

我正在编写一些使用名为 vault 的库的代码。在这个库中,我们有一个 client。我的代码使用了这个 client 但我希望能够轻松测试使用它的代码。我只使用库中的几个方法,因此我最终创建了一个接口:

type vaultclient interface {
    logical() *api.logical
    settoken(v string)
    newlifetimewatcher(i *api.lifetimewatcherinput) (*api.lifetimewatcher, error)
}

现在,如果我的代码指向这个 interface ,那么一切都很容易测试。除了让我们看看 logical() 方法。它在这里返回一个 struct 。我的问题是,这个 logical 结构也有允许您 readwrite 的方法,例如:

func (c *logical) read(path string) (*secret, error) {
    return c.readwithdata(path, nil)
}

这些也被用在我的项目中,以执行以下操作:

{{ VaultClient defined above }}.Logical().Write("something", something)

问题就在这里。从调用 .logical() 返回的 logical 有一个我无法模拟的 .write.read 方法。我不希望这些方法中的所有逻辑都在我的测试中运行。

理想情况下,我希望能够执行与上面类似的操作,并为 logical 创建一个 interface 。我对 golang 比较陌生,但我正在努力寻找最好的方法。据我所知,这是不可能的。嵌入不像继承那样工作,所以看起来我必须返回一个logical。这使得我的代码无法像我希望的那样简单地进行测试,因为 logical 方法中的所有逻辑都无法被模拟。

我有点不知所措。我在谷歌上搜索了这个问题的答案,但没有人谈论过这种情况。它们仅达到我为客户端使用初始 interface 的程度。

这是常见情况吗?我使用的其他库不会像 logical 那样返回 structs。相反,它们通常只返回一个平淡的 struct 来保存数据并且没有方法。


解决方案


package usecasevaultclient

// usecase.go
type VaultClient interface {
    Logical() *api.Logical
    SetToken(v string)
    NewLifetimeWatcher(i *api.LifetimeWatcherInput) (*api.LifetimeWatcher, error)
}

type vaultClient struct {
   repo RepoVaultClient
}

// create new injection
func NewVaultClient(repo RepoVaultClient) VaultClient {
  return &vaultClient{repo}
}

func(u *vaultClient) Logical() *api.Logical {
 // do your logic and call the repo of
   u.repo.ReadData()
   u.repo.WriteData()
}
func(u *vaultClient) SetToken(v string) {}
func(u *vaultClient) NewLifetimeWatcher(i *api.LifetimeWatcherInput) (*api.LifetimeWatcher, error)

// interfaces.go
type RepoVaultClient interface {
   ReadData() error
   WriteData() error
}

// repo_vaultclient_mock.go
import "github.com/stretchr/testify/mock"

type MockRepoVaultClient struct {
   mock.Mock
}

func (m *MockRepoVaultClient) ReadData() error {
      args := m.Called()
      return args.Error(0)
}

func (m *MockRepoVaultClient) WriteData() error {
      args := m.Called()
      return args.Error(0)
}


// vaultClient_test.go

func TestLogicalShouldBeSuccess(t *testing.T) {
  mockRepoVaultClient = &MockRepoVaultClient{}

  useCase := NewVaultClient(mockRepoVaultClient)

  mockRepoVaultClient.On("ReadData").Return(nil)
  mockRepoVaultClient.On("WriteData").Return(nil)

  // your logics gonna make this response as actual what u implemented
  response := useCase.Logical()

  assert.Equal(t, expected, response)
}

如果你想测试 logical 的接口,你需要使用 testify/mock 来模拟 readdata 和 writedata ,这样你就可以定义这些方法返回的响应,你可以在调用接口的新注入后进行比较

以上就是《增加Go库方法的可测试性的方法》的详细内容,更多关于的资料请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>