测试该方法是否在Golang处理程序中调用

时间:2018-09-18 07:40:53

标签: unit-testing go

我正在Golang中实现API。我有一个端点,在其中我正在调用具有其他包参数的方法。现在,我需要检查一下,该方法是否已在请求中调用。

下面是我正在做的和期望得到的类似的小场景。

我的经理

package myPackage
import (
    "log"
    "github.com/myrepo/notifier" // my another package
)

func MyHandler(writer http.ResponseWriter, request *http.Request) { 
    // ...
    // ...

    notifier.Notify(4, "sdfsdf")

    // ...
    // ...

}

测试处理程序

func TestMyHandler(t *testing.T) {
    // Here I want to 
    req, _ := http.NewRequest("GET", "/myendpoint", nil)
    // ... Want to test that notifier.Notify is called
    // ...
}

在TestMyHandler中,我要检查notifier.Notify是否已调用。

发现

我试图了解AssertNumberOfCallsfunc (*Mock) Calledfunc (*Mock) MethodCalled,但不确定如何使用它们:(。

我是Golang的新手,因此真的很激动。 如果我错过了任何事情,请让我知道,否则您可能需要更多信息以了解更多信息。

2 个答案:

答案 0 :(得分:2)

  

想测试notifier.Notify被调用。

不,你不知道。您对处理程序做了应做的事情感兴趣,这似乎由两件事组成:

  1. 返回正确的响应(易于使用net / http / httptest.ResponseRecorder进行测试),并且

  2. 有一些明显的副作用,在这里发出一些通知。

要测试2.您测试发出了通知,而不是调用了某些函数。 无论notify.Notify结果如何(例如数据库条目,文件,某些HTTP调用)都应进行测试。正式地,这不再是单元测试,但是对副作用的测试绝不是严格的单元测试。

您可以做什么:将处理程序逻辑包装到某个对象中并观察该对象的状态。丑陋。不要。

答案 1 :(得分:1)

这是使用依赖项注入和接口的好机会。

即,我们需要提取Notifier

的概念

(警告:未直接测试代码)

type Notifier interface {
    Notify(int, string)() error
}

现在要避免与notifier库混淆,请使用本地别名。

import "github.com/myrepo/notifier" mynotifier

然后,因为您正在使用的库将其作为函数导出,而不是在结构内,所以我们需要制作一个实现我们接口的结构

type myNotifier struct {}

func (mn *myNotifier) Notify(n int, message string) error {
  return mynotifier.Notify(n, message)
}

然后您修改功能:

func MyHandler(writer http.ResponseWriter, request *http.Request, notifier Notifier) { 
    // ...
    // ...

    notifier.Notify(4, "sdfsdf")

    // ...
    // ...

}

然后在测试中,您现在可以自由发送间谍通知程序

type spyNotifier struct {
  called boolean
}

func (n *spyNotifier) Notify(n int, msg string) error {
  n.called = true
  return
}