【问题标题】:create unit test for ws in golang在 golang 中为 ws 创建单元测试
【发布时间】:2017-12-05 02:17:38
【问题描述】:

我使用gorilla web socket框架,使用如下客户端在本地运行web socket并调试

https://github.com/gorilla/websocket

ws = new WebSocket("ws://localhost:8080/mypath")
ws.onmessage = function(ev) { console.log(ev.data) }
ws.send("hello")

当我在 chrome 控制台中使用它时这是有效的,但我的问题是是否有办法在 go 中进行一些单元测试并避免使用 chrome 控制台?

【问题讨论】:

  • 我没有使用过 gorilla 或 websockets,但你应该能够放松你的测试约束,方法是在你的测试中初始化一个服务器(实际上是通过套接字绑定),然后在另一个中使用一个测试客户端去日常与它互动。这至少可以让您使用 websocket 协议并通过网络堆栈验证您的服务器是否正常运行,但当然不会验证您的服务器是否通过 chrome..
  • @dm03514 - 因为我是这个主题的新手,如果你能提供一些例子会很棒......谢谢!

标签: go websocket


【解决方案1】:

使用net/http/httptest 包创建test server。使用 Gorilla 客户端连接到该服务器。读写消息以测试连接。

package main

import (
    "net/http"
    "net/http/httptest"
    "strings"
    "testing"

    "github.com/gorilla/websocket"
)

var upgrader = websocket.Upgrader{}

func echo(w http.ResponseWriter, r *http.Request) {
    c, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        return
    }
    defer c.Close()
    for {
        mt, message, err := c.ReadMessage()
        if err != nil {
            break
        }
        err = c.WriteMessage(mt, message)
        if err != nil {
            break
        }
    }
}

func TestExample(t *testing.T) {
    // Create test server with the echo handler.
    s := httptest.NewServer(http.HandlerFunc(echo))
    defer s.Close()

    // Convert http://127.0.0.1 to ws://127.0.0.
    u := "ws" + strings.TrimPrefix(s.URL, "http")

    // Connect to the server
    ws, _, err := websocket.DefaultDialer.Dial(u, nil)
    if err != nil {
        t.Fatalf("%v", err)
    }
    defer ws.Close()

    // Send message to server, read response and check to see if it's what we expect.
    for i := 0; i < 10; i++ {
        if err := ws.WriteMessage(websocket.TextMessage, []byte("hello")); err != nil {
            t.Fatalf("%v", err)
        }
        _, p, err := ws.ReadMessage()
        if err != nil {
            t.Fatalf("%v", err)
        }
        if string(p) != "hello" {
            t.Fatalf("bad message")
        }
    }
}

【讨论】:

  • 当我在根目录中运行go tes 时出现以下错误:runtime.main_main·f: relocation target main.main not defined runtime.main_main·f: undefined: "main.main"
  • 我只是用这个文件创建了一个新的golang项目,然后我尝试运行它……可以吗?
  • 在 GOPATH 的目录中,将上述内容保存到名为 echo_test.go 的文件中。从该目录运行go test 命令。如果这不起作用,那么您的本地 Go 配置有问题。见the Go documentation for more information about testing
  • 上面的解决方案很好用。我建议一个小小的改进:我相信使用url.Parses.URL 解析为URL 结构然后使用u.Scheme = "ws" 更改URL 的方案会更优雅。这是一个工作示例:play.golang.org/p/QiOkv8s608s
  • @IlijaEftimov 字符串操作代码简短、快速,可以处理httphttps。尽管此答案中未使用https,但我认为显示可与https 一起使用的转换很重要。基于url.Parse的更完整的转换参见play.golang.org/p/0WXHNFOptkq
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多