2017-08-16 52 views
0

我正在開展項目,我的任務是爲一個軟件包編寫一些測試。測試需要訪問不同包中的全局變量。這個全局變量可能是在不同軟件包的測試中設置/訪問的。因爲默認情況下,測試會針對不同的包並行運行。因此,設置/訪問此變量可能會創建競爭條件。什麼是最好的方式來同步不同包中涉及全局變量的測試?

最簡單的同步方法是創建一個跨越不同包的共享sync.Mutex。話雖如此,我試圖把這個sync.Mutex放在聲明全局變量的xxx.go的xxx_test.go中,不幸的是,由於範圍的限制,另一個軟件包無法訪問這個Mutex。最終,我發現我必須將這個sync.Mutex添加到專門用於測試的實用程序包中,然後不同的程序包可以訪問此Mutex以實現該全局變量的同步目的。

我是新郎朗。我只是覺得我需要創建一個實用程序包來實現測試中的同步目的很尷尬,另一方面,如果另一個開發人員在另一個包中做了一些測試,他/她可能不知道在哪裏可以找到這個sync.Mutex。有沒有更好的方法來實現這個同步的目的與一個優雅的解決方案。

非常感謝!

+2

這是原因之一,爲什麼不推薦使用全局變量...: ) – cd1

+0

確實,謝謝。 –

回答

2

這個問題不可能廣泛。 Entire books已被寫入主題。

但是,由於您具體詢問全局變量,最簡單的答案是:不要使用全局變量。

我們總是被教導全局變量是一種反模式。測試是全局變量和單例是反模式的主要原因之一。

如果可能,請將您的全局狀態重構爲,至少允許爲實例變量,而不是全局。然後,您可以將該實例傳遞給您的函數進行測試。

作爲一個簡單的例子,假設你有以下的全局變量,以及使用它的功能:

var globalFoo = 123 

func doFoo() string { 
    return fmt.Sprintf("foo = %d", globalFoo) 
} 

修改你的函數把你的變量作爲自變量:

func doFoo(foo int) string { 
    return fmt.Sprintf("foo = %d", foo) 
} 

這如果你的全局狀態是一個數據庫連接或大量的變量,可能會更復雜,但原理是一樣的:不要使用全局變量;而不是傳遞變量。

在傳統的代碼庫,一個方法,以允許測試,而無需改變你的函數的簽名,是創建簡單的環繞功能:

func doFoo() string { 
    return realDoFoo(globalFoo) 
} 

func realDoFoo(foo int) string { 
    fmt.Sprintf("foo = %s", foo) 
} 
+0

感謝您的回答,這是非常有益的! –

相關問題