在Go中测试构造函数

How I can test my NewClient constructor for my Client struct ?

package busybus

import (
    "bufio"
    "net"
)

type Client struct {
    counter  integer
    conn     net.Conn
    bufin    *bufio.Reader
    bufout   *bufio.Writer
    messages chan string
    state    string
}

func NewClient(conn net.Conn, messages chan string) *Client {
    return &Client{
        counter:  0,
        conn:     conn,
        bufin:    bufio.NewReader(conn),
        bufout:   bufio.NewWriter(conn),
        messages: messages,
        state:    "waiting",

    }
}

I tried some testing like this:

package busybus

import (
    "net"
    "testing"
)

func TestNewClient(t *testing.T) {
    ln, _ := net.Listen("tcp", ":65535")
    conn, _ := ln.Accept()
    messages := make(chan string)

    client := NewClient(conn, messages)
    if client.conn != conn {
        t.Errorf("NewClient(%q, %q).conn == %q, want %q", conn, messages, client.conn, conn)
    }
}

But this hangs during the test runs due to ln.Accept, it seems a totally wrong approach anyway... any suggestion how I can test this constructor ?

Some code is so short and simple that ensuring that the test is correct is more complicated than ensuring that the code itself is correct. Your constructor is such code.

What I would do is either not test it at all, or just call it (using some dummy implementation of net.Conn) to ensure that it doesn't blow up in smoke when called (therefore called a smoke test).

Later you can test it as part of a bigger test (integration test), where you have a real server to connect to, and which uses your client struct to talk to it.

If you ever find a bug that is due to this constructor, then first add a test that demonstrates the problem, then fix it. Then you will have your test :-)

A test should check that the constructor "works as intended". Checking the value of client.conn is hardly checking any intended behavior, as the value of an unexported field is not behavior. It just checks HOW the struct and constructor is implemented, not WHAT it implements. Test the what, not the how.

By the way, you could maybe embed a *ReadWriter in your client.

client.buf = bufio.NewReadWriter(...)

In addition to what @bjarke-ebert said.

There are no constructors in Go, they are just normal functions. Test them as you would test any other function. If a function is too complex to test then probably there is a way to change the design to make it more testable.

Also from my experience tests that check internal details of implementation too much (like the test from the question) are very hard to maintain as they constantly need to be updated.