这个问题是this one的后续问题.我想要一个简单的测试https://pkg.go.dev/github.com/alexedwards/scs/v2@v2.5.1来验证我想使用的功能.基本上,我只想将一些数据放入会话中,取出它,并验证它们是否相同.类似于:

func TestScs_SetGetIsSame1(t *testing.T) {
    sessionManager := scs.New()
    req := httptest.NewRequest("GET", "/", nil)
    key := "boolean"
    expected := false
    sessionManager.Put(req.Context(), key, expected)
    actual := sessionManager.GetBool(req.Context(), key)
    assert.Equal(t, expected, actual)
}

这会导致死机:scs:上下文中没有会话数据.

我try 复制example from the httptest package,但HTTPest.Server不实现HTTP.Handler(缺少方法ServeHTTP).

func TestScs_SetGetIsSame2(t *testing.T) {
    sessionManager := scs.New()

    ts := httptest.NewServer((http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello, client")
        expected := true
        sessionManager.Put(r.Context(), "key", expected)
        actual := sessionManager.GetBool(r.Context(), "key")
        assert.Equal(t, expected, actual)
    })))
    defer ts.Close()

    res, err := http.Get(ts.URL)
    if err != nil {
        log.Fatal(err)
    }

    greeting, err := io.ReadAll(res.Body)
    res.Body.Close()
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("%s", greeting)

    sessionManager.LoadAndSave(ts)
}

我也查看了tests in the alexedwards/scs repository,但它们使用私有函数addSessionDataToContext.

测试围棋的最好、最简单的方法是什么?

推荐答案

我在你的代码里看到了

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // ...
}))

sessionManager.LoadAndSave(ts) // this line is incorrect

您正在try 通过测试服务器(ts)到sessionManager.LoadAndSave.这不会起作用,因为sessionManager.LoadAndSave需要http.Handler,而ts的类型是*httptest.Server,而不是http.Handler.

相反,您应该在创建测试服务器之前将实际处理程序传递给sessionManager.LoadAndSave.

为此,在将其传递给httptest.NewServer之前,您将用sessionManager.LoadAndSave包装实际的处理程序函数(它确实返回http.Handler).

handler := sessionManager.LoadAndSave(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // ... logic here ...
}))

ts := httptest.NewServer(handler)

这将通过用sessionManager.LoadAndSave中间件包装您的实际处理程序函数来创建一个新的处理程序.然后,该包装的处理程序被传递到httptest.NewServer.

如果你把所有这些都放在一起:

package main

import (
    "fmt"
    "github.com/alexedwards/scs/v2"
    "github.com/stretchr/testify/assert"
    "io"
    "log"
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestScs_SetGetIsSame2(t *testing.T) {
    sessionManager := scs.New()

    // Create a handler and wrap it using sessionManager.LoadAndSave
    handler := sessionManager.LoadAndSave(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "Hello, client")
        expected := true
        sessionManager.Put(r.Context(), "key", expected)
        actual := sessionManager.GetBool(r.Context(), "key")
        assert.Equal(t, expected, actual)
    }))

    // Create a test server with the handler
    ts := httptest.NewServer(handler)
    defer ts.Close()

    // Make a request to the server
    res, err := http.Get(ts.URL)
    if err != nil {
        log.Fatal(err)
    }

    // Read the response body
    greeting, err := io.ReadAll(res.Body)
    res.Body.Close()
    if err != nil {
        log.Fatal(err)
    }

    // Print the response body
    fmt.Printf("%s", greeting)
}

Go相关问答推荐

为什么在GO中打印变量会导致堆栈溢出?

Golang XML密钥名称冲突

使用一元或服务器流将切片从GRPC服务器返回到客户端

在GO中创建[]字符串类型的变量

如何在gofiber/websocket/v2中设置状态代码和原因

Python样式生成器实现为通道:过早读取

Redis:尽管数据存在,但 rdb.Pipelined 中出现redis:nil错误

为什么 Go 对于长度为 100k 的切片使用的内存比长度为 100k 的数组要少?

仅使用公共 api 对 alexedwards/scs 进行简单测试

如何在 Go msgraph-sdk-go 中转发消息并包括抄送和/或密送收件人?

如何将一片十六进制字节转换为整数

为什么时间很短.睡眠时间比基准测试中要求的(约 300 ns)长?

使用 `didip/tollbooth` 限制每小时最大请求数

有没有办法判断值是否满足接口中定义的类型约束?

Go AST:获取所有 struct

在 Golang 中使用 OR 条件验证 struct 的两个字段

如何在 Go 中使用 Pact 返回错误请求(400、500)?

go routine 和接收错误或成功的通道

Gin中测试模式有什么用

如何动态解析 Go Fiber 中的请求正文?