Testing Golang with Martini:模拟测试示例
我已经整理了一段代码,它不会影响我的路线。我想用mocking测试一下。我是一个能干的测试能手,所以任何提示都非常感谢 My Generate Routes.go为当前URL生成路由。 片段: 这是在my server.go中调用的:Testing Golang with Martini:模拟测试示例,testing,go,mocking,martini,Testing,Go,Mocking,Martini,我已经整理了一段代码,它不会影响我的路线。我想用mocking测试一下。我是一个能干的测试能手,所以任何提示都非常感谢 My Generate Routes.go为当前URL生成路由。 片段: 这是在my server.go中调用的: var configuration = app.LoadConfiguration(os.Getenv("MYENV")) // Our Martini API Instance var apiInstance *martini.Martini func in
var configuration = app.LoadConfiguration(os.Getenv("MYENV"))
// Our Martini API Instance
var apiInstance *martini.Martini
func init() {
apiInstance = martini.New()
// Setup middleware
apiInstance.Use(martini.Recovery())
apiInstance.Use(martini.Logger())
// Add the request context middleware to support contexual data availability
reqContext := &app.LRSContext{ }
reqContext.SetConfiguration(configuration)
producer := app.ConfigProducer(reqContext)
reqContext.SetProducer(producer)
apiInstance.MapTo(reqContext, (*abstract.RequestContext)(nil))
// Hook in the OAuth2 Authorization object, to be processed before all requests
apiInstance.Use(app.VerifyAuthorization)
// Connect to the DB and Inject the DB connection into Martini
apiInstance.Use(app.MongoDBConnect(reqContext))
// Add the ResponseEncoder to allow JSON encoding of our responses
apiInstance.Use(app.ResponseEncoder)
// Add Route handlers
r := martini.NewRouter()
stateRouter := routes.StateRoute{}
stateRouter.GenerateRoutes(&r)
// Add the built router as the martini action
apiInstance.Action(r.Handle)
}
我的疑问是:
type mockedStateRoute struct {
// How can I mock the stateRoute struct?
mock.Mock
}
type mockedEncoder struct {
mock.Mock
}
type mockedMongoDB struct {
mock.Mock
}
type mockedReqContext struct{
mock.Mock
}
type mockedRespWriter struct{
mock.Mock
}
type mockedReq struct{
mock.Mock
}
func (m *mockedStateRoute) testGetStatesRoute(m1 mockedEncoder,
m2 mockedMongoDB, m3 mockedReqContext,
m4 mockedReqContext, m5 mockedRespWriter,
m6 mockedReq) (string) {
args := m.Called(m1,m2,m3,m4,m5,m6)
fmt.Print("You just called /states/GET")
// 1 is just a test value I want to return
return 1, args.Error(1)
}
func TestSomething (t *testing.T) {
testObj := new(mockedStateRoute)
testObj.On("testGetStatesRoute", 123).Return(true,nil)
// My target function that does something with mockedStateRoute
// How can I call the GET function in GenerateRoutes(). Or should I, since martini is handling all my requests
}
我提到的链接:
为了进行依赖项注入,要测试的东西需要有某种方式来接收其依赖项。在您的代码中,到mongodb的连接是在测试自身的初始化过程中完成的,这不允许在模拟的情况下注入看起来像mongo连接的东西 实现依赖关系的方法有很多,但是进行依赖关系注入的最简单和最直接的方法之一是,在创建依赖关系时,让要测试的东西接收依赖关系,这样它的上下文就是配置依赖关系的具体实现的地方。看看: 实例需要实现一个
数据存储
才能工作,它不需要知道任何关于其内部的信息,唯一重要的是它使用两种方法实现接口,Get
和Set
。实际上,作为单元测试的一般规则,您只想测试代码,而不想测试依赖项。在本例中,它在“生产”中使用Redis,但在测试中:
type MockedDataStore struct {
mock.Mock
}
func (m *MockedDataStore) Get(k string) string {
args := m.Called(k)
return args.String(0)
}
func (m *MockedDataStore) Set(k, v string) {
m.Called(k, v)
}
除了让框架检查它是否被调用之外,它没有任何功能。在测试本身中,您必须使用以下内容配置期望值:
d := new(MockedDataStore)
...
d.On("Set", "foo", "42").Return().Once()
...
d.On("Get", "foo").Return("42").Once()
当然,使用模拟对象初始化实例,并对其进行测试:
d := new(MockedDataStore)
instance := NewAppInstance(d)
d.On("Get", "foo").Return("42").Once()
request, _ = http.NewRequest("GET", "/get/foo", nil)
response = httptest.NewRecorder()
instance.ServeHTTP(response, request)
d.AssertExpectations(t)
因此,作为总结,请更具体地回答您的问题:
martini
提供的方法ServeHTTP
生成对HTTP请求的响应,并使用httptest.NewRecorder()
模拟响应的接收。当然,如果您的应用程序具有HTTP接口之外使用的更复杂的功能,您也可以将其作为常规方法进行测试非常感谢你!这就是我要找的。一旦我决定实施它,我会有更多的问题。如果我真的卡住了,我还能在这个帖子里打扰你吗?当然,没问题,一点也不麻烦,我也从Go开始:)
d := new(MockedDataStore)
...
d.On("Set", "foo", "42").Return().Once()
...
d.On("Get", "foo").Return("42").Once()
d := new(MockedDataStore)
instance := NewAppInstance(d)
d.On("Get", "foo").Return("42").Once()
request, _ = http.NewRequest("GET", "/get/foo", nil)
response = httptest.NewRecorder()
instance.ServeHTTP(response, request)
d.AssertExpectations(t)