在Go语言中测试构造函数

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

Testing constructors in Go

问题

我如何测试Client结构体中的NewClient构造函数?

package busybus

import (
    "bufio"
    "net"
)

type Client struct {
    counter  int
    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",
    }
}

我尝试了以下测试:

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

但是由于ln.Accept导致测试运行时挂起,这似乎是完全错误的方法... 有什么建议可以测试这个构造函数吗?

英文:

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 ?

答案1

得分: 7

有些代码非常简短和简单,以至于确保测试的正确性比确保代码本身的正确性更加复杂。你的构造函数就是这样的代码。

我会做的是要么不进行任何测试,要么只是调用它(使用一些虚拟的net.Conn实现)来确保在调用时不会出错(因此称为烟雾测试)。

稍后,您可以将其作为更大的测试(集成测试)的一部分进行测试,其中您有一个真实的服务器进行连接,并使用您的客户端结构与其通信。

如果您发现由于这个构造函数而导致的错误,那么首先添加一个演示问题的测试,然后修复它。然后你就有了你的测试 在Go语言中测试构造函数

一个测试应该检查构造函数“按预期工作”。检查client.conn的值几乎不检查任何预期行为,因为未导出字段的值不是行为。它只检查结构体和构造函数的实现方式,而不是实现的内容。测试“是什么”,而不是“怎么样”。

顺便说一下,您可以在客户端中嵌入一个*ReadWriter。

client.buf = bufio.NewReadWriter(...)
英文:

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 在Go语言中测试构造函数

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

答案2

得分: 1

除了@bjarke-ebert所说的之外。

Go语言中没有构造函数,它们只是普通的函数。像测试其他函数一样测试它们。如果一个函数太复杂而无法测试,那么可能有一种方法可以改变设计,使其更易于测试。

此外,根据我的经验,过于关注实现细节的测试(如问题中的测试)很难维护,因为它们需要不断更新。

英文:

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.

huangapple
  • 本文由 发表于 2015年12月2日 06:34:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/34031510.html
匿名

发表评论

匿名网友

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

确定