#go #testing #websocket
#Вперед #тестирование #websocket
Вопрос:
Итак, по сути, я пишу тест go для своего приложения для чата, и по какой-то причине, если я напишу функцию Test_saveMessage в верхней части этого файла, мои тесты пройдут, и они будут работать нормально, однако, если я напишу Test_InitRouter в верхней части этого файла — мой сервер откроется, и тест не завершится. Как будто он будет прослушивать дополнительные запросы. Кто-нибудь знает причину, по которой это может происходить? Вот код, который не работает:
package messenger
import (
"fmt"
"github.com/gorilla/websocket"
"github.com/stretchr/testify/assert"
"net/http/httptest"
"strings"
"testing"
)
var testMessage = Message{
Username: "Name",
Message: "Test message"}
//Tests InitRouter both sending and receiving messages
func Test_InitRouter(t *testing.T) {
var receivedMessage Message
//Create test server with the InitRouter handler
s := httptest.NewServer(InitRouter())
defer s.Close()
// Convert URL from http to ws
u := "ws" strings.TrimPrefix(s.URL, "http")
fmt.Println(u)
// Connect to the test server
ws, _, err := websocket.DefaultDialer.Dial(u, nil)
if err != nil {
t.Fatalf("%v", err)
}
defer ws.Close()
//Send message to the server read received message and see if it's the same
if err != ws.WriteJSON(testMessage) {
t.Fatalf("%v", err)
}
err = ws.ReadJSON(amp;receivedMessage)
if err != nil {
t.Fatalf("%v", err)
}
if receivedMessage != testMessage {
t.Fatalf("%v", err)
}
}
//Test for the saveMessage function
func Test_saveMessage(t *testing.T) {
saveMessage(testMessage)
assert.Equal(t, 1, len(messages), "Expected to have 1 message")
}
Как только я перемещаю функцию Test_saveMessage наверх, она начинает работать должным образом.
Вот код для обработчика:
package messenger
import (
"fmt"
"github.com/go-chi/chi"
"github.com/gorilla/websocket"
log "github.com/sirupsen/logrus"
"net/http"
)
func InitRouter() http.Handler {
r := chi.NewRouter()
r.Get("/", GetWebsocket)
return r
}
var clients = make(map[*websocket.Conn]bool) // connected clients
var broadcast = make(chan Message) // broadcast channel
var messages = []Message{}
func GetWebsocket(w http.ResponseWriter, r *http.Request) {
// Upgrade initial GET request to a websocket
upgrader := websocket.Upgrader{}
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Error(err)
}
// Close the connection when the function returns
defer ws.Close()
// Register our new client and send him the chat history
clients[ws] = true
serveInitialMessages(ws)
//initialize message sending logic
sendMessages(ws)
}
// Sends messages from a particular websocket to the channel
func sendMessages(ws *websocket.Conn){
for {
var msg Message
// Read in a new message as JSON and map it to a Message object
err := ws.ReadJSON(amp;msg)
if err != nil {
log.Info(err)
delete(clients, ws)
break
}
// Send the newly received message to the broadcast channel
broadcast <- msg
saveMessage(msg)
}
}
func HandleMessages() {
for {
// Grab the next message from the broadcast channel
msg := <-broadcast
fmt.Println(msg)
// Send it out to every client that is currently connected
for client := range clients {
err := client.WriteJSON(msg)
if err != nil {
log.Printf("error: %v", err)
client.Close()
delete(clients, client)
}
}
}
}
func saveMessage(m Message) {
if len(messages) >= 50 {
messages = messages[1:]
}
messages = append(messages, m)
}
func serveInitialMessages(ws *websocket.Conn) {
for _, m := range messages {
err := ws.WriteJSON(m)
if err != nil {
log.Error(err)
}
}
}
Комментарии:
1. Покажите код, который устанавливает
messages
.2. Добавлен код в сообщение.
3. Тесты зависят от порядка из-за общего состояния в переменной уровня пакета
messages
. Сбрасывайте эту переменную в каждом тесте. Поскольку сервер не отправляет сообщение клиента обратно клиенту немедленно, он блокирует вечное ожидание сообщения, когда нет сохраненных сообщений.Test_InitRouter
Приложение и тест имеют несколько циклов обработки данных.4. Ну, я попытался добавить строку
messages = []Message{}
в оба теста, но это не помогло. Возможно ли, чтоmessages
проблема не в переменной?5. Очистка сообщений устраняет зависимость от порядка тестирования. Теперь вам нужно исправить застрявший тест и гонки данных.