2016-04-13 59 views
1

我在單元測試中遇到了一個我一直無法解決的問題。我認爲最簡潔的說法是:在xUnit/Shouldly/AutoMoq/Autofixture中,我們可以使用InlineAutoMoqData傳入一個Type,它可以在測試中用作<T>?

我希望能夠使用Theory inlineAutoMoqData參數中提供的Type作爲Shouldly的Should.Throw方法中的T.這將允許我創建不同的行測試(我猜這是該框架中的內聯理論),期望不同的異常類型,如果有多個與方法關聯。

我不確定是否有可能,但這裏是單元測試本身的一個例子。

[Theory] 
[InlineAutoMoqData("bork", typeof(FileTypeNotRecognizedException))] 
public void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, Type expected, ProcessFactory sut) 
{ 
    Should.Throw<expected>(() => sut.Build(fileName)); 
} 

我看着這些問題在之前得到難倒並張貼此,分別爲:Dynamically Create a generic type for templateCreating a Generic<T> type instance with a variable containing the Type

是這樣的可能嗎?

編輯:

我看到在我的xUnit可以通過Assert.Throws(類型,代表)方法實現這一目標。

[Theory] 
[InlineAutoMoqData("bork", typeof(FileTypeNotRecognizedException))] 
public void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, Type expected, ProcessFactory sut) 
{ 
    Assert.Throws(expected,() => sut.Build(fileName)); 
} 

我仍然想知道是否有辦法實現它,只要我希望Type屬於通用方法。

回答

1

除了使用Reflection之外,您不能使用類似於您提到的兩個鏈接。

但是,你可以做一些小技巧來實現你想要的。這是醜陋的和不切實際的,我不建議使用它,但只是爲了好玩...

創建一個包含您的參數測試泛型類:

public class Test<T> where T : Exception 
{ 
    public virtual void Build_ReturnsSpecificException_FileNamePassedIn(
     string fileName, 
     ProcessFactory sut) 
    { 
     Assert.Throws<T>(() => sut.Build(fileName)); 
    } 
} 

對於每一個參數(異常型)創建一個類從通用的一個繼承,重寫測試方法,並使用InlineAutoMoqData

public class TestFileNotFound : Test<FileTypeNotRecognizedException> 
{ 
    [Theory] 
    [InlineAutoMoqData("bork")] 
    public override void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, 
     ProcessFactory sut) 
    { 
     base.Build_ReturnsSpecificException_FileNamePassedIn(fileName, sut); 
    } 
} 
public class TestAnotherException : Test<Exception> 
{ 
    [Theory] 
    [InlineAutoMoqData("borg")] 
    public override void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, 
     ProcessFactory sut) 
    { 
     base.Build_ReturnsSpecificException_FileNamePassedIn(fileName, sut); 
    } 
} 

當然,你可以使用一個通用的方法,而不是一個泛型類做同樣的,但似乎愚蠢的好:

public void Build_ReturnsSpecificException_FileNamePassedIn<TException>(string fileName, 
    ProcessFactory sut) 
    where TException : Exception 
{ 
    Assert.Throws<TException>(() => sut.Build(fileName)); 
} 

[Theory] 
[InlineAutoMoqData("bork")] 
public void Build_ReturnsSpecificException_FileNamePassedIn(string fileName, 
    ProcessFactory sut) 
{ 
    Build_ReturnsSpecificException_FileNamePassedIn<FileTypeNotRecognizedException>(fileName, sut); 
} 

[Theory] 
[InlineAutoMoqData("borg")] 
public void Build_ReturnsAnotherException_FileNamePassedIn(string fileName, 
    ProcessFactory sut) 
{ 
    Build_ReturnsSpecificException_FileNamePassedIn<Exception>(fileName, sut); 
} 

當你發現你自己,xUnit.net具有非通用Assert.Throws,需要一個Type,你應該使用,而不是這個技巧的。

+0

爲什麼不在基類測試中放置'[Theory]'和'[InlineAutoMoqData]'屬性? http://blog.ploeh.dk/2011/05/09/GenericunittestingwithxUnit.net那麼你不需要所有的覆蓋。 –

+0

如果內聯數據(fileName)不依賴於異常,那麼您是對的。這似乎並非如此。看起來這個異常會隨着fileName的變化而改變,否則,根本不需要內聯這個異常? –

相關問題