如何测试实现gorilla上下文的函数

时间:2014-10-16 19:18:30

标签: go

我编写了一个将数据保存到redis数据库服务器的函数。挑战在于我想测试这些功能,而不知道如何测试它。

我只是以某种方式开始

功能

package sessrage

/*
 * Save data into redis database. In the common case,
 * the data will be only valid during a request. Use
 * hash datatype in redis.
 */

import (
    "../context"
    "github.com/garyburd/redigo/redis"
    "net/http"
)

const (
    protocol string = "tcp"
    port     string = ":6379"
)

func connectAndCloseRedis(connectCall func(con redis.Conn)) {

    c, err := redis.Dial("tcp", ":6379")
    defer c.Close()
    if err != nil {
        panic(err.Error())
    }
    connectCall(c)
}

func PostSessionData(r *http.Request, key, value string) {

    go connectAndCloseRedis(func(con redis.Conn) {
        sessionId := context.Get(r, context.JwtId).(string)
        con.Do("HMSET", sessionId, key, value)
    })
}

func GetSessionData(r *http.Request, key string) interface{} {

    var result interface{}

    sessionId := context.Get(r, context.JwtId).(string)
    reply, _ := redis.Values(c.Do("HMGET", sessionId, key))
    redis.Scan(reply, &result)
    return result
}

和测试文件

package sessrage

import (
    //"fmt"
    "../context"
    . "github.com/smartystreets/goconvey/convey"
    "github.com/stretchr/testify/assert"
    "net/http"
    "net/http/httptest"
    "testing"
    "time"
)

var server *httptest.Server
var glrw http.ResponseWriter
var glr *http.Request

func init() {
    server = httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
        glrw = rw
        glr = r

        context.Set(glr, context.JwtId, "TestId")
    }))

}

func TestPostAndGetSession(t *testing.T) {

    Convey("POST and GET data on redis.", t, func() {

        PostSessionData(glr, "key1", "value1")

        time.Sleep(time.Second * 10)
        v := GetSessionData(glr, "key1")

        assert.Equal(t, "value1", v)
    })
}

当我尝试运行测试时,我已经

an't load package: ......./sessrage.go:10:2: local import "../context" in non-local package

,上下文包看起来像

package context

import (
    "github.com/gorilla/context"
    "net/http"
)

type contextKey int

const (
    LanguageId contextKey = iota
    JwtId
)

func Get(r *http.Request, key interface{}) interface{} {
    return context.Get(r, key)
}

func Set(r *http.Request, key, val interface{}) {
    context.Set(r, key, val)
}

我错了什么?

这是我第一次和http一起测试代码。这似乎很难测试。

1 个答案:

答案 0 :(得分:1)

有一些问题:

  • 不要使用相对导入路径。
  • 使用pool而不是在每个操作上拨打redis。
  • 如果调用链中的多路复用器或更高级别的内容在goroutine之前清除Gorilla上下文,则对PostSessionData匿名函数中的sessionId:= context.Get(r,context.JwtId)。(string)的调用可能会失败运行。这样做:

    func PostSessionData(r *http.Request, key, value string) {
        c := pool.Get()
        defer c.Close()
        sessionId := context.Get(r, context.JwtId).(string)
        if err := c.Do("HMSET", sessionId, key, value); err != nil {
           // handle error
        }
    }