我应该如何使用gorilla上下文对中间件包进行单元测试

时间:2016-05-10 16:15:54

标签: testing go

我有这个网络/ http服务器设置链中有几个中间件,我找不到如何测试这些中间件的例子...

我使用gorilla / mux路由器的基本net / http,一个Handle看起来像这样:

r.Handle("/documents", addCors(checkAPIKey(getDocuments(sendJSON)))).Methods("GET")

在这些中我汇总了一些数据并通过Gorilla Context context.Set方法提供它们。

通常我用httptest测试我的http函数,我希望也可以用这些来测试它们,但是我无法弄清楚如何以及我对最好的方法感到好奇。我应该单独测试每个中间件吗?我是否应该在需要时预填充适当的上下文值?我可以一次测试整个链,这样我就可以在输入时检查所需的状态吗?

1 个答案:

答案 0 :(得分:3)

我不会测试涉及大猩猩或任何其他第三方套餐的任何内容。如果你想测试以确保它有效,我会为你正在运行的应用版本(例如C.I.服务器)的端点设置一些外部测试运行器或集成套件。

相反,请单独测试您的中间件和处理程序 - 就像您可以控制的那样。

但是,如果您正在测试堆栈(mux - > handler - > handler - > handler - > MyHandler),那么就可以使用函数作为vars全局定义中间件可以提供帮助:

//creating a data access class is one way to connect to your db by passing in db path
Dim context As New Namespace.YourContext(New DataAccessClass() With {.Path = aBrowsedForSDFFileTextBoxMaybe.Text})
Dim listOfTableObjects As List(Of Namespace.TableObject) = New List(Of Namespace.TableObject)

    For n = 1 To SomethingRelatedToRows
    Dim tableObject As New Namespace.TableObject() With {
                    .entityProp1 = TableObject(n).entityProp1,
                    .entityProp2 = TableObject(n).entityProp2,
                    .entityProp3 = TableObject(n).entityProp3,
                    .entityProp4 = TableObject(n).entityProp4,
                    .entityProp5 = TableObject(n).entityProp5,
                    .entityProp6 = TableObject(n).entityProp6
                }

        listOfTableObjects.Add(tableObject)

    Next n

    //.TableObjects being the DbSet from the ...Context.vb file
    context.TableObjects.AddRange(listOfTableObjects) 
    context.SaveChanges()

在正常使用期间,它们的实施与变化保持一致。

var addCors = func(h http.Handler) http.Handler {
  ...
}

var checkAPIKey = func(h http.Handler) http.Handler {
  ...
}

但是对于单元测试,你可以覆盖它们:

r.Handle("/documents", addCors(checkAPIKey(getDocuments(sendJSON)))).Methods("GET")

如果您发现自己经常复制粘贴此锅炉板代码,请将其移至单元测试中的全局模式:

// important to keep the same package name for
// your test file, so you can get to the private
// vars.
package main

import (
  "testing"
)

func TestXYZHandler(t *testing.T) {

  // save the state, so you can restore at the end
  addCorsBefore := addCors
  checkAPIKeyBefore := checkAPIKey

  // override with whatever customization you want
  addCors = func(h http.Handler) http.Handler {
    return h
  }
  checkAPIKey = func(h http.Handler) http.Handler {
    return h
  }

  // arrange, test, assert, etc.
  //

  // when done, be a good dev and restore the global state
  addCors = addCorsBefore
  checkAPIKey = checkAPIKeyBefore
}

关于单元测试终点的附注......

由于中间件应该使用合理的默认值(预期正常传递而不是你想要在func中测试的基础数据流的互斥状态),我建议在实际的主要处理函数的上下文之外对中间件进行单元测试

这样,您就可以严格按照中间件进行一组单元测试。另一组测试完全集中在您调用的URL的主要处理程序上。它使新手更容易发现代码。