我正在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
是否已调用。
我试图了解AssertNumberOfCalls,func (*Mock) Called和func (*Mock) MethodCalled,但不确定如何使用它们:(。
我是Golang的新手,因此真的很激动。 如果我错过了任何事情,请让我知道,否则您可能需要更多信息以了解更多信息。
答案 0 :(得分:2)
想测试notifier.Notify被调用。
不,你不知道。您对处理程序做了应做的事情感兴趣,这似乎由两件事组成:
返回正确的响应(易于使用net / http / httptest.ResponseRecorder进行测试),并且
有一些明显的副作用,在这里发出一些通知。
要测试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
}