gpt4 book ai didi

unit-testing - Go 中最惯用的方法是测试依赖于具有大量方法的结构的代码?

转载 作者:IT王子 更新时间:2023-10-29 01:21:29 28 4
gpt4 key购买 nike

假设我有一个 UserRepository 结构,它封装了与数据库交互的逻辑。这个结构有一组方法,比如:

  • 查找全部()
  • findById()
  • 查找名称()
  • 保存()
  • 等等....

还有另一个结构(例如,我们称之为 UserService)依赖于 UserRepository 结构。

为了测试 UserService,我需要模拟 UserRepository 的功能。我知道这样做的唯一方法是为 UserRepository 提供接口(interface)并使 UserService 依赖于它而不是 UserRepository 结构。它将允许创建接口(interface)的模拟实现,并在测试中将其设置为 UserService 的依赖项。

最惯用的方法是什么?

1) 如果 UserService 仅依赖于 1 个 UserRepository 的方法(假设是 findAll)——我是否仍应定义一个包含所有存储库方法的接口(interface),或者最好仅为该方法定义一个单独的接口(interface)并将其用作用户服务?如果是这样,它(接口(interface))的最佳名称是什么?如果另一个结构将依赖于 findAll() 和 findById() 方法,我是否应该再次创建另一个接口(interface)?

2) 为这些接口(interface)存储模拟的最佳位置在哪里?是否可以重复使用它们?或者对于不同结构的测试,我需要重新定义模拟?

附言对我来说,单元测试是项目中非常重要的一部分。我想让它们尽可能可读,避免样板代码并专注于它们的逻辑。因此,在不同的测试文件中为相同的接口(interface)创建多个模拟实现对我来说是一个糟糕的选择,因为它会降低测试代码的可读性。

最佳答案

1) 我同意 elevine 所说的,即只需要该结构所需的方法。例如:您有 UserService 需要 FindByNameFindAll,以及 UserAdminService 需要 FindByIdFindAllSave。在那种情况下,您应该有两个接口(interface):

  1. UserProviderFindByNameFindAll
  2. UserAdminProvider,带有 FindByIdFindAllSave

这还可以让您控制 UserProvider,例如你知道它不能调用 Save,所以它不能修改用户。

您可能只需要一个满足这两个接口(interface)的实际实现。

2) 查看testify/mockmockery . Mockery 将在 mocks 子包中为您的接口(interface)生成模拟,每个接口(interface)一个。这确实意味着您不能对两个测试使用相同的模拟结构,但这并不重要,因为代码是生成的。您不会在模拟结构中模拟接口(interface)的行为,而是通过设置期望在测试中进行模拟,例如:

func TestThatYouCantLoginWithNonexistentUser(t *testing.T) {
userRepository := new(mocks.UserRepository)
userService := user.NewService(userRepository)
// if the userService calls UserRepository.FindByName("joe"), it will return nil, since there's no such user.
userRepository.On("FindByName", "joe").Return(nil)
_, err := userService.Login("joe", "password")
// err should not be nil and the message should be "user does not exist"
assert.EqualError(t, err, "user does not exist")
// assert that the expectations were met, i.e. FindByName was called with "joe"
userRepository.AssertExpectations(t)
}

这实际上使测试更容易理解,因为当您调用 FindByName("joe") 时,您不必去检查模拟所做的一些其他文件。

关于unit-testing - Go 中最惯用的方法是测试依赖于具有大量方法的结构的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38660219/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com