unit-testing - 在 Go-kit 中为 make 处理函数编写单元测试

标签 unit-testing go

我的问题特定于 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/

相关文章:

http - 如何在 golang 中获取重定向 url 而不是页面内容?

unit-testing - 如何避免集成测试中的业务逻辑重复

c# - 如何在 VSTS 上配置单元测试名称/描述?

java - Mockito 中的嵌套模拟

ruby - 如何重置对模拟类方法的期望?

postgresql - 套接字 : operation not permitted when connecting to cloudsql

go - 根据 fmt.Errorf 返回的错误检查(值或类型)

unit-testing - MIME 解析器测试数据

go - 由于同一包中的 undefined object ,dlv 调试失败

go - 如何创建一个不会被复制且不能为空的函数参数