wstest

package module
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 23, 2019 License: Apache-2.0 Imports: 5 Imported by: 10

README

wstest

Build Status codecov GoDoc Go Report Card

A websocket client for unit-testing a websocket server

The gorilla organization provides full featured websocket implementation that the standard library lacks.

The standard library provides a httptest.ResponseRecorder struct that test an http.Handler without ListenAndServe, but is helpless when the connection is being hijacked by an http upgrader. As for testing websockets, it has the httptest.NewServer that actually listens on a socket on an arbitrary port.

This package provides a NewDialer function to test just the http.Handler that upgrades the connection to a websocket session. It runs the handler function in a goroutine without listening on any port. The returned websocket.Dialer then can be used to dial and communicate with the given handler.

Get

go get -u github.com/posener/wstest

Examples

See the example test.

An example how to modify a test function from using httptest.Server to use wstest.NewDialer function.

func TestHandler(t *testing.T) {
	var err error

	h := &myHandler{}
-	s := httptest.NewServer(h)
-	defer s.Close()
-	d := websocket.Dialer{}
+	d := wstest.NewDialer(h)

-	c, resp, err := d.Dial("ws://" + s.Listener.Addr().String() + "/ws", nil)
+	c, resp, err := d.Dial("ws://" + "whatever" + "/ws", nil)
	if err != nil {
		t.Fatal(err)
	}
	
	if got, want := resp.StatusCode, http.StatusSwitchingProtocols; got != want {
		t.Errorf("resp.StatusCode = %q, want %q", got, want)
	}
	
	err = c.WriteJSON("test")
	if err != nil {
		t.Fatal(err)
	}
}

Documentation

Overview

Package wstest provides a NewDialer function to test just the `http.Handler` that upgrades the connection to a websocket session. It runs the handler function in a goroutine without listening on any port. The returned `websocket.Dialer` then can be used to dial and communicate with the given handler.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewDialer

func NewDialer(h http.Handler) *websocket.Dialer

NewDialer creates a wstest recorder to an http.Handler which accepts websocket upgrades. This send an HTTP request to the http.Handler, and wait for the connection upgrade response. it runs the recorder's ServeHTTP function in a goroutine, so recorder can communicate with a client running on the current program flow

h is an http.Handler that handles websocket connections. It returns a *websocket.Dial struct, which can then be used to dial to the handler.

Example
package main

import (
	"fmt"
	"net/http"

	"github.com/gorilla/websocket"
	"github.com/posener/wstest"
)

func main() {
	var (
		// simple echo dialer
		s = &echoServer{}

		// create a dialer to the dialer
		// this send an HTTP request to the http.Handler, and wait for the connection
		// upgrade response.
		// it uses the gorilla's websocket.Dial function, over a fake net.Conn struct.
		// it runs the handler's ServeHTTP function in a goroutine, so the handler can
		// communicate with a client running on the current program flow
		d = wstest.NewDialer(s)

		resp string
	)

	c, _, err := d.Dial("ws://example.org/ws", nil)
	if err != nil {
		panic(err)
	}

	// the client is also a websocket.Conn object, so all websocket functions
	// can be used with it. here we write a JSON string to the connection.
	c.WriteJSON("hello echo server")

	// Reading from the socket is done with the websocket.Conn functions as well.
	c.ReadJSON(&resp)
	fmt.Println(resp)

	// Pass another message in the connection
	c.WriteJSON("byebye")
	c.ReadJSON(&resp)
	fmt.Println(resp)

	// Finally close the connection
	err = c.Close()
	if err != nil {
		panic(err)
	}

	<-s.Done

}

type echoServer struct {
	upgrader websocket.Upgrader
	Done     chan struct{}
}

func (s *echoServer) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	var (
		err error
	)

	s.Done = make(chan struct{})
	defer close(s.Done)

	if r.URL.Path != "/ws" {
		w.WriteHeader(http.StatusNotFound)
		return
	}

	var conn *websocket.Conn
	conn, err = s.upgrader.Upgrade(w, r, nil)
	if err != nil {
		return
	}

	for {
		var msg string
		err := conn.ReadJSON(&msg)
		if err != nil {
			return
		}
		conn.WriteJSON(msg + "!")
	}
}
Output:

hello echo server!
byebye!

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL