2015-12-01 127 views
0

如何測試我的NewClient構造函數是否適用於我的Client結構?在Go中測試構造函數

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", 

    } 
} 

我嘗試了一些測試是這樣的:

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在試運行期間該掛起,這似乎是一個完全錯誤的做法反正...任何建議如何測試這個構造?

回答

2

一些代碼非常簡短,以確保測試正確比確保代碼本身是正確的更復雜。 你的構造函數就是這樣的代碼。

我要做的是要麼根本不測試它,要麼只是調用它(使用一些虛擬實現net.Conn)以確保它在調用時不會冒煙(因此稱爲煙霧測試)。

稍後,您可以將其作爲更大測試(集成測試)的一部分進行測試,您需要一臺真正的服務器進行連接,並使用您的客戶端結構與其交流。

如果您發現由此構造函數引起的錯誤,請首先添加一個演示此問題的測試,然後對其進行修復。然後你會有你的測試:-)

測試應該檢查構造函數「按預期工作」。檢查client.conn的值很難檢查任何預期的行爲,因爲未導出字段的值不是行爲。它只是檢查結構和構造函數是如何實現的,而不是它實現的。測試一下,而不是如何。

順便說一下,你可能會在你的客戶端中嵌入一個* ReadWriter。

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

感謝您對讀者的建議。除此之外,我不同意。當然,這是一個簡單的構造函數,由於它的簡單性,它甚至不是必需的,但是當我有一些更復雜的初始化過程時,我想首先檢查它,而不是稍後搜索我的驗收測試失敗的原因。你寫了一個虛擬連接,你的意思是簡單地滿足net.Conn接口嗎? – astropanic

+1

@astropanic:你寫過「但當我有一些更復雜的初始化過程」:目前你沒有它。爲什麼現在打擾一些可能從未發生過的事情?你的構造函數只返回一個填充的結構體。只是測試一下。在測試中不需要迷戀。 – Volker

1

除了@ bjarke-ebert所說的。

Go中沒有構造函數,它們只是普通函數。像測試任何其他功能一樣測試它們。如果一個函數太複雜,無法測試,那麼可能有一種方法來改變設計,使其更具可測試性。

另外從我的經驗來看,太多檢查內部實現細節的測試(如來自問題的測試)非常難以維護,因爲它們經常需要更新。

+0

是一個構造函數不是一個正常的功能呢?你在暗示什麼,而不是我的函數來初始化結構?假設我有一些代碼需要初始化更多這樣的客戶結構。我認爲如果沒有這個功能,當功能需要更改時,我以後會有更多的代碼來重寫。我在不同的Golang項目中看到過這種模式很多次,並且閱讀它是使用New或NewType的常見做法,也許我錯了(仍然在學習Go),我願意提供建議,thx – astropanic

+2

您的問題明確詢問測試構造函數。我只是提出了一點,你應該測試它們作爲其他功能。如你所提供的例子那樣擁有'NewClient'函數是非常有意義的。 – kostya

+0

再詳細一點:'NewClient'功能沒問題。但是測試conn字段是由NewClient初始化的沒有任何意義,因爲它應該已經被其他測試間接測試過了。測試不是免費的。您需要編寫它們,讓它們保持最新狀態,增加測試套件執行時間等。 – kostya