![](/img/trans.png)
[英]How to test if a method of an object is called inside completion handler block using OCMock?
[英]Test that method is called in handler in Golang
我正在用 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 的新手,真的很高兴能做到这一点。 如果我遗漏了任何内容,请告诉我,否则您可能需要更多信息以了解更多信息。
要测试那个notifier.Notify被调用。
不,你不会。 您对处理程序做了应做的事情感兴趣,这似乎由两件事组成:
返回正确的响应(易于使用net / http / httptest.ResponseRecorder进行测试),然后
有一些明显的副作用,在这里发出一些通知。
要测试2.您测试发出了通知,而不是调用了某些函数。 无论notify.Notify结果如何(例如数据库条目,文件,某些HTTP调用),都应进行测试。 正式地,这不再是单元测试,但是对副作用的测试绝不是严格的单元测试。
您可以做什么:将处理程序逻辑包装到某个对象中并观察该对象的状态。 丑陋。 别。
这是使用依赖项注入和接口的好机会。
即,我们需要提取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
}
这种方法类似于Mathew 的 answer<\/a> ,但使用testify<\/a>中的mock<\/a>包。 在这里,您创建 Notifier 的模拟实现,注册方法调用,并断言已使用预期参数调用了该方法。
测试<\/h1>package handler_test import ( "net\/http" "net\/http\/httptest" "testing" ) func TestMyHandler(t *testing.T) { t.Parallel() mockNotifier := MockNotifier{} handler := Handler{ notifier: &mockNotifier } \/\/ register the mock to expect a call to Notify with the given arguments and return nil as the error mockNotifier.On("Notify", 4, "sdfsdf").Return(nil) \/\/ setup the test arguments request := httptest.NewRequest(http.MethodGet, "\/someapi", nil) writer := httptest.NewRecorder() \/\/ call the handler handler.MyHandler(writer, request) \/\/ this is the important part!! \/\/ this ensures that the mock Notify method was called with the correct arguments, otherwise the test will fail mockNotifier.AssertExpectations(t) }<\/code><\/pre>"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.