简单测试alexedwards/scs,仅使用公共API。

huangapple go评论102阅读模式
英文:

Simple test for alexedwards/scs using only the public api

问题

这个问题是对这个问题的后续问题。我想要一个简单的测试来验证我想要使用的函数,测试的网址是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)
}

这会导致 panic: scs: no session data in context。

我尝试复制httptest 包中的示例,但是 httptest.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)
}

我还查看了 alexedwards/scs 仓库中的测试,但它们使用了一个私有函数 addSessionDataToContext。

在 Go 中,测试会话的最佳、最简单的方法是什么?

英文:

This question is a follow-up question to this one. I would like a simple test for https://pkg.go.dev/github.com/alexedwards/scs/v2@v2.5.1 to verify the functions I would like to use. Basically, I just want to put some data into the session, pull it out, and verify it is the same. Something like:

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)
}

This gives panic: scs: no session data in context.

I tried copying the example from the httptest package, but httptest.Server does not implement http.Handler (missing method 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)
}

I also looked at the tests in the alexedwards/scs repository, but they use a private function addSessionDataToContext.

What is the best, most simple way to test sessions in go?

答案1

得分: 1

我在你的代码中看到了以下内容:

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

sessionManager.LoadAndSave(ts) // 这一行是错误的

你试图将测试服务器 (ts) 传递给 sessionManager.LoadAndSave。这样是行不通的,因为 sessionManager.LoadAndSave 需要一个 http.Handler,而 ts 的类型是 *httptest.Server,而不是 http.Handler

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

为此,你需要使用 sessionManager.LoadAndSave 将实际的处理程序函数包装起来(它返回一个 http.Handler),然后将其传递给 httptest.NewServer

handler := sessionManager.LoadAndSave(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    // ... 在这里编写逻辑 ...
}))

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()

    // 创建一个处理程序并使用 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)
    }))

    // 使用处理程序创建一个测试服务器
    ts := httptest.NewServer(handler)
    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)
}

希望对你有所帮助!

英文:

I see in your code

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

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

You are trying to pass the test server (ts) to sessionManager.LoadAndSave. This will not work because sessionManager.LoadAndSave expects an http.Handler, and ts is of type *httptest.Server, not http.Handler.

Instead, you should pass the actual handler to sessionManager.LoadAndSave before creating the test server.

For that, you would wrap the actual handler function with sessionManager.LoadAndSave (which does return a http.Handler) before passing it to httptest.NewServer.

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

ts := httptest.NewServer(handler)

That creates a new handler by wrapping your actual handler function with the sessionManager.LoadAndSave middleware. This wrapped handler is then passed to httptest.NewServer.

If you bring it all together:

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)
}

huangapple
  • 本文由 发表于 2023年7月4日 02:23:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76607300.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定