2013-07-01 90 views
3

讓單元測試方法說我有下面的類結構:使用了全局變量

private string GlobalVariable = "foo"; 

public void MainMethod() 
{ 
    string bar = Baz(); 
} 

public string Baz() 
{ 
    return GlobalVariable + "qux"; 
} 

我想進行使用不同的值GlobalVariableBaz()單元測試。然而,由於GlobalVariable只是在方法中調用,並沒有作爲參數傳遞給它,所以我不能在我的單元測試方法中設置它。

所以我考慮換個結構:

private string GlobalVariable = "foo"; 

public void MainMethod() 
{ 
    string bar = Baz(GlobalVariable); 
} 

public string Baz(string globalVar) 
{ 
    return globalVar + "qux"; 
} 

這樣,現在我可以改變,以檢查不同的輸出在我的單元測試的參數值globalVar

但是,我的第一個結構更清潔,因爲我沒有不必要地將變量值作爲參數傳遞給方法。

有沒有辦法讓兩個世界的最好,而不必妨礙我的結構,以便運行單元測試?

+2

不......這就是靜態類難以測試的原因。正如你所發現的那樣,全球狀態並不好。 –

+1

等等..這是靜態的嗎?在你的例子中,什麼定義了「全局」? –

+0

我想問的是如何/爲什麼你的'GlobalVariable'在真實世界中使用時會發生變化?如果不是,那麼你是否真的需要測試它?如果它確實發生了變化,那麼通過什麼機制和測試機制。 – Belogix

回答

5

我會受到誘惑,有一個單獨的重載方法,那麼我可以有一個與參數和一個沒有...

public string Baz() 
{ 
    return Baz(GlobalVariable); 
} 

public string Baz(string globalVar) 
{ 
    return globalVar + "qux"; 
} 

這樣做的好處是,你仍然有你無參數的方法,可以從代碼中調用,而不必擔心每次都指定值,但是那樣會導致測試過載,以及在需要使用不同值時。

儘管您仍然無法測試使用不同值的第一種方法,但我認爲假設測試第二個函數只是足夠的是安全的。


或者,如果您使用的是C#4.0中,你可以使用optional parameters代替:

public string Baz(string globalVar = null) 
{ 
    if(string.IsNullOrEmpty(globalVar)) 
     globalVar = GlobalVariable; 
    return globalVar + "qux"; 
} 
+2

重載聽起來像是一個好主意,它會給我兩個好處。但是,我必須確保將其記錄得很好,否則,在類中看不到可用的重載方法可能會讓其他開發人員感到困惑!這是該場景的標準做法嗎?看起來這將是單元測試的一個常見問題,但是我找不到以前解決方案的任何參考。 – Curt

+0

那麼,對我來說,「標準實踐」往往是「我想做的任何事情」。如果這是我從來沒有需要克服的東西,然後我纔會覺得它會很好地工作。如果我在6個月後找到任何問題,那麼下次我需要解決同樣的問題時,我可以嘗試一種不同的方法。我之前肯定使用過這種方法,當我想要默認參數時,但也允許偶爾的覆蓋,並且我沒有經歷任何會讓我有理由在將來再次避免使用它的理由。 – musefan

+0

我已經實現了這個解決方案。我已經改變了我對這造成混亂的想法,我認爲通過傳遞值作爲參數使得方法更多地是不依賴於局外人變量的「單元/組件」。 – Curt

2

如果全局變量是不變的(如應用程序和設置),我不會使用過載。相反,我會訪問測試代碼中的應用程序設置。所以,我會留下這樣的:

public string Baz() 
{ 
    return ApplicationSetting.GlobalVariable + "qux"; 
} 

然後在測試中,我會做這樣的事情:

[Test] 
public void Test() 
{ 
    string expected = ApplicationSetting.GlobalVariable + "qux"; 
    Assert.AreEqual(expected, Baz()); 
} 

然後,兩個被測代碼和本身都使用相同的應用程序設置測試資源。這意味着源可以更改,但測試不會中斷。希望這可以幫助。