【问题标题】:Is DI(dependency injection) necessary for mocking dependencies in golang?在 golang 中模拟依赖项是否需要 DI(依赖项注入)?
【发布时间】:2020-04-14 18:02:05
【问题描述】:

当我尝试对如下函数进行单元测试时,extern_pkg 是要模拟的外部包:

import "extern_pkg"

func MyFunc() {
  ...
  extern_pkg.F()
}

func main() {
  MyFunc()
}

我阅读了一些博客,它们似乎都是通过使用依赖注入修改产品代码来实现的。例如如下:

type exter interface {
  F()
}

func MyFunc(e exter) {
  ...
  e.F()
}

type extpkg struct{}

func (extpkg) F() {extern_pkg.F()}

func main() {
  epkg := extpkg{}
  MyFunc(epkg)
}

然后在测试代码中,创建一个满足exter接口的mock对象,并作为参数传递给MyFunc

我的问题是:

  1. 如果MyFunc函数包含许多要模拟的外部包,我是否需要DI每个作为函数参数?函数所依赖的任何全局变量也是如此吗?
var global_var

func MyFunc() {
  ...
  extern_pkg1.F()
  ...
  extern_pkg2.G()
  ...
  extern_pkg3.H()
  ...
  global_var
}
  1. 有没有办法避免修改产品代码?

谢谢!

【问题讨论】:

  • 这是一个干净的设计问题,因为问题代码目前与第 3 方外部依赖项紧密耦合
  • 你不能模拟或注入一个包,这不是包的工作方式。您可以模拟或注入类型和函数,但不能模拟包 - 没有可以传递的“包值”。
  • @Adrian 好的,那么我的意图是模拟包中的类型和函数。对我的问题有什么想法吗?
  • 至 Q1:是的,您需要 DI 每一个。如果您有一个具有许多依赖项的函数,那是一种代码味道,表明它应该被重构。 Q2:不清楚你在问什么。如果您的产品代码无法按原样测试,那么您必须对其进行修改以进行测试,对吧?

标签: unit-testing go dependency-injection


【解决方案1】:

尝试使用 func 类型的 var 并注入它们。它更容易,不需要更少的代码和接口。见godif

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 1970-01-01
    • 2019-12-25
    相关资源
    最近更新 更多