2017-10-17 108 views
2

我會盡量簡化單元測試中遇到的問題。靜態值的單元測試

我測試靜態私有字段的方法。如果我運行測試,那麼我必須能夠預測靜態場的價值。當我有一個測試,或者如果我逐個運行測試,這不是問題。比一切工作正常。

問題是,當我有一個以上的單元測試,改變靜態值和運行它們。 在這種情況下,只有第一次測試纔會通過,其他所有測試都會失敗。

這是簡化的例子:

using Xunit; 

namespace My.Unit 
{ 
    public class UnitTests 
    { 
     [Fact] 
     public void test1() 
     { 
      var obj = new TestClass(); 
      var res = obj.testMethod(); 

      Assert.Equal(1, res); 
     } 

     [Fact] 
     public void test2() 
     { 
      var obj = new TestClass(); 
      var res = obj.testMethod(); 

      Assert.Equal(1, res); 
     } 
    } 

    public class TestClass 
    { 
     private static int staticValue = 0; 
     public TestClass() 
     { 
      ++staticValue; 
     } 

     public int testMethod() 
     { 
      return staticValue; 
     } 
    } 
} 

我會從每一個單元測試期望有靜態領域的新的壽命,但是這並不是如此。

+3

這取決於您的單元測試 - ** **選手有實現它爲每個測試或沒有新的流程,從而新的應用程序域。無論如何,我建議重置靜態變量,如果需要反射。 – HimBromBeere

+1

引入像staticValue這樣的全局變量是一個糟糕的設計。你能否將TestClass實例化爲一個全局可訪問的字段?更好,把它放入容器。 – qxg

+0

如果你想測試的代碼 - 不使用可變的靜態變量,或配置測試跑步者或測試框架運行影響的試驗順序 – Fabio

回答

2

根據單元測試亞軍,你可能會或可能不會對每個測試幾個過程。所以如果有疑問,我不會過多地指望它,並嘗試自行重置靜態。

在你的情況下,該成員是你必須使用反射來做到這一點,最好在每testrun建立一個私有字段:

[Setup] 
public void SetupTest() 
{ 
    var field = typeof(TestClass).GetField("staticValue", BindingFlags.Static | BindingFlags.NonPublic); 
    if(field != null) 
     field.SetValue(null, 0); 
} 

正如你看到的初始化有效的測試用例與靜是相當哈克和繁瑣。如何規避這個問題沒有一般的規則。通常static甚至不需要,有時你可以介紹一些你可以模擬的工廠。

+0

是的,這是正確的,只是在我的情況下,我使用的xUnit所以設置使用的構造。 – Raskolnikov