2017-02-22 85 views
0

我有一個uni-test的基本設置:它測試一個負責索引目錄中的文件的類,並繼續按需提供正確的文件。 爲此,我使用system.io.abstractions庫提供的模擬文件系統。基本設置如下:NUnit,可以在「ValueSource」之前運行「setup」嗎?

[TestFixture] 
public class ImageDataTests 
{ 
    private static MockFileSystem fs; 
    private const int TESTNUM = 3; 
    [SetUp] 
    public static void Init() { 
     var allnamegroups = TestSettings.NameGroupFactory(TESTNUM); 
     fs = new MockFileSystem(); 
     foreach (string[] namegroup in allnamegroups) { 
      var dname = ImageData.MakeDirectoryName(namegroup[0], namegroup[1]); 
      TestSettings.AddTestFilesToMockFileSystem(fs, dname); 
     } 
    } 
} 

現在每個測試工作在這種情況下,並測試(比如說)「刷新」功能我下面的方法添加到上面的類:

public static IEnumerable<ImageData> ImgDatSource() { 
     while (true) { 
      yield return new ImageData("test", fs); 
     } 
    } 
    [Test, Sequential] 
    public void GetAllOfTypeTest(
     [ValueSource(nameof(ImgDatSource))] ImageData img, 
     [Values("foo", "bar", "this")]string type, 
     [Values(1, 2, 0)]int ex) { 
     Assert.That(() => img.GetAllOfType(type).Count(), Is.EqualTo(ex)); 
    } 

這應該(現在)列出以「foo」,「bar」和「this」開頭的所有文件。 - 失敗,說明找不到目錄。 - 即使在第一次測試運行之前:在初始化Imagedata。 調試驗證我的想法:當ValueSource嘗試初始化輸入時,Init()尚未運行。

有沒有辦法做「這樣」的測試,但缺少在測試體內初始化Imagedata? (或者失去參數化結構+測試索引,或者不得不手動編寫許多類似的測試)。

請注意,我真的需要運行文件系統生成器的每個測試:雖然上面的測試很簡單,並沒有太大的作用。一些測試將適應/更改文件系統,以針對更多邊緣情況測試該類。 - 也在測試過程中。

回答

0

NUnit的執行有兩個階段:加載(發現)測試和運行測試。 OneTimeSetUp,SetUp,測試方法執行,TearDown和OneTimeTearDown都是運行測試的一部分。

在運行測試之前,會發生測試加載,如您所預料的那樣。您的數據源(TestCaseSource或ValueSource)都在加載階段運行。

這導致了兩個結論: 1.您的SetUp和其他測試執行方法中的任何內容都不可能影響用於測試的數據。 2.您的數據源需要提供數據參數,以允許您在運行時創建對象,而不是對象本身。

在你的例子中,我會改變測試方法來取四個參數,用img替換爲「test」和fs。我會添加一行到每個測試的開始,通過調用一個建模在你的Init之後的助手方法來創建imagedata。

+0

我可以通過某種方式自動生成該行到每個函數,也許通過運行一個不同的宏?這是代碼重複,這是我認爲應該始終防止的事情。 – paul23

+0

我在部分同意。測試中的代碼複製通常很有用,因爲它使得每個測試都是獨立的。不過,在這種情況下,如果有辦法避免它會更好。我能想到的唯一方法是參數化燈具並在OneTImeSetUp中創建圖像數據。然而,這可能比僅僅在每種方法中添加代碼更有效。 – Charlie

相關問題