我的问题特定于 Go-kit 以及如何在其中组织代码。 我正在尝试为以下功能编写单元测试:
func MakeHandler(svc Service, logger kitlog.Logger) http.Handler {
orderHandler := kithttptransport.NewServer(
makeOrderEndpoint(svc),
decodeRequest,
encodeResponse,
)
r := mux.NewRouter()
r.Handle("/api/v1/order/", orderHandler).Methods("GET")
return r
编写适当的单元测试的正确方法是什么?我见过如下例子:
sMock := &ServiceMock{}
h := MakeHandler(sMock, log.NewNopLogger())
r := httptest.NewRecorder()
req := httptest.NewRequest("GET", "/api/v1/order/", bytes.NewBuffer([]byte("{}")))
h.ServeHTTP(r, req)
然后测试请求的主体和 header 。但这似乎不是一个合适的单元测试,因为它调用了代码的其他部分 (orderHandler
)。是否可以只验证从 MakeHandler()
返回的内容而不是在请求期间?
最佳答案
TL;DR:是的,该测试的方向是正确的。你不应该尝试测试 返回的处理程序的内部结构,因为该第三方包可能会以您 future 未预料到的方式发生变化。
Is it possible to just validate what's returned from MakeHandler() instead of during a request?
不是很好。 MakeHandler()
返回一个接口(interface),理想情况下你会使用
只是测试中的接口(interface)方法。
您可以查看 mux.NewRouter()
返回类型的文档,看看是否
具体类型中有任何字段或方法可以为您提供
信息,但这可能会很痛苦——无论是为了理解
测试(一种很少使用的类型来了解)以及由于 future
对 mux
包的修改可能会影响您的代码,而不会破坏
测试。
What would be the correct way of writing a proper unit test?
您的示例实际上是在正确的方向上。在测试 MakeHandler()
时,
您正在测试它返回的处理程序是否能够处理所有路径
并为每个路径调用正确的处理程序。所以你需要调用
ServeHTTP()
方法,让它做它自己的事,然后测试它是否有效
正确。仅内省(introspection)处理程序并不能保证期间的正确性
实际使用。
不过,您可能需要提出实际有效的请求,这样您才能理解 根据响应主体或 header 调用了哪个处理程序。那应该 使测试达到一个相当合理的状态。 (我想你已经知道了)
同样,我会为将来添加的每条路线添加一个基本的子测试。 可以在单独的函数中编写详细的处理程序测试。
关于unit-testing - 在 Go-kit 中为 make 处理函数编写单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52281320/