Golang:在调用 Init 方法之前模拟接口方法

发布于 2025-01-15 22:18:57 字数 534 浏览 3 评论 0原文

如何模拟在包 init() 方法中调用的内容?

例如:

ma​​in.go


var myService MyService = myservicepkg.New()

func init(){
   response := myService.get()
}

func otherMethod(){
   //do something
}

ma​​intest.go

func Test_otherMethod(){
  ctrl := NewController(t)
  defer ctrl.Finish()
  myServiceMock = myservicepkg.NewMock(myService)

  myServiceMock.EXPECT().get().return("success")
}

问题是在服务被mock替换之前调用了init()

How can I mock something that gets called in a package init() method?

For example:

main.go


var myService MyService = myservicepkg.New()

func init(){
   response := myService.get()
}

func otherMethod(){
   //do something
}

maintest.go

func Test_otherMethod(){
  ctrl := NewController(t)
  defer ctrl.Finish()
  myServiceMock = myservicepkg.NewMock(myService)

  myServiceMock.EXPECT().get().return("success")
}

The problem is that init() is called before the service is replaced by the mock.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

扛刀软妹 2025-01-22 22:18:57

这是与可变的全球国家合作的问题。

我的建议是添加一个标志,以便在某些条件下不运行它,或者公开一个可以在内部测试中恢复/更新此全局变量的私有函数。

这反映了您的设计:如果测试很复杂,也许您应该重构。

创建一个带有字段Service的对象Application,在构造函数/构建器/工厂上创建将更容易测试。

init的使用非常微妙。除了将驱动程序注册到 sql 包中之外,我从不使用它(可能是为了处理标志)。

也许你可以在你的设计中添加更多的面向对象

This is the issue of work with a mutable global state.

My advice is to add a flag to not run this on certain conditions or expose a private function that can recover/update this global variable in an internal test.

This reflects your design: if it is complicate to test, perhaps you should refactor.

Create an object Application with a field Service, created on the constructor/builder/factory will be easier to test.

The usage of init is very delicate. Besides register a driver into sql packages, I never use it (perhaps to handle flags).

Perhaps you can add more OO to your design

梦里泪两行 2025-01-22 22:18:57

您需要在 init() 内调用 otherMethod()。否则不能在 init() 之前调用它。

You will need to call the otherMethod() inside init(). It can't be called before init() otherwise.

机场等船 2025-01-22 22:18:57

我找到了一个解决方法,您可以阻止 init 代码在测试中执行,并像这样单独测试该方法:

func init(){
  if len(os.Args) > 0 && strings.HasSuffix(os.Args[0], ".test") {
    log.Printf("skipping jwt.init() for testing")
  } else if len(os.Args) > 1 && strings.HasSuffix(os.Args[1], "-test.run") {
    log.Printf("skipping jwt.init() for testing")
  } else { 
    response := myService.get()
  }
}

这将阻止调用 init 服务调用。

I found a workaround, you can prevent the init code from being executed in your test and test the method in isolation like this:

func init(){
  if len(os.Args) > 0 && strings.HasSuffix(os.Args[0], ".test") {
    log.Printf("skipping jwt.init() for testing")
  } else if len(os.Args) > 1 && strings.HasSuffix(os.Args[1], "-test.run") {
    log.Printf("skipping jwt.init() for testing")
  } else { 
    response := myService.get()
  }
}

This will prevent the init service calls from being called.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文