2016-09-21 91 views
0

我正在測試類的方法。但是,其中一些具有非相關內容的屬性,這使得測試失敗。從C#中的模擬對象中刪除方法屬性

例如,我有這個類(在VB.net但可能是C#以及)

<AttributeOne()> 
<AttributeTwo(Arg1, Arg2)> 
Public Overridable Function SomeMethod() As Object 
    ' Stuff 
End Function 

當我打電話SomeMethod從我的嘲笑對象,它將提出一些例外,因爲屬性嘗試做一些東西在單元測試環境中是不可能的。

[TestFixture] 
public class SomeClassUnitTests 
{ 
    [Test] 
    public void TestSomeMethod() 
    { 
     var someClassMock = new Mock<SomeClass>() { CallBase = true }; 

     //Exception is thrown 
     var result = someClassMock.Object.SomeMethod(); 
    } 
} 

測試寫在C#。我正在使用MoqNunit

如何在單元測試時忽略這些屬性?

+1

如果這樣,你違反了單一責任原則是這樣的。當您應該解決原因時,您正試圖治療症狀。 –

+0

@HimBromBeere我正在測試'SomeMethod',並且此方法具有一些評估全局安全信息的屬性(例如,如果用戶已登錄並且有東西)。然而,在單元測試中沒有這樣的信息,所以測試失敗了,我無法測試該方法,明白了嗎? – RafaelC

+0

@DavidL你能再詳細一點嗎? – RafaelC

回答

0

我想我明白你要在這裏做什麼,但它不適用於Mocks,因爲即使你創建了一個模擬SomeClass,你也必須模擬SomeMethod函數 - 你不能使用真正的!

這意味着你沒有測試它,只是測試它的模擬版本。

但是,爲什麼不試試這個沒有Mocks?

您可以使SomeOtherMethod爲虛擬,然後子集SomeClass僅用於此測試。 然後,您可以編寫任何您喜歡的SomeOtherMethod函數的重寫;當你打電話給真實的SomeClass.SomeMethod時,它會調用該覆蓋版本。

即(對不起,C#這樣做是我的VB是生鏽)假設SomeClass看起來是這樣,選擇一個故意無用的功能,以免混淆:

public class SomeClass 
{ 
    public virtual int SomeMethod() 
    { 
     return SomeOtherMethod()/2; 
    } 

    protected virtual SomeOtherMethod() 
    { 
     return [some crazy maths] 
    } 
} 

你想測試SomeMethod正確返回一半是SomeOtherMethod

所以,現在你可以做到這一點,在測試項目:

public class SomeClassTestDouble: SomeClass 
{ 
    protected override int SomeOtherMethod() 
    { 
     return 2; 
    } 
} 

那麼在您的測試:

var sut = new SomeClassTestDouble(); 
var expected = 1; 
var actual = sut.SomeMethod(); 
Assert.Equal(expected, actual) 

現在你已經測試了SomeMethod按預期工作,沒有任何嘲諷。事實上很多人會爭辯說,除非你跨越了架構或系統邊界,否則你更喜歡Mocks上的測試雙打(包括存根)。我不會說如果我同意或不一般,但在這種情況下,我認爲最好不要模仿。

注意事項

請記住re。屬性 - 他們不應該做任何事情直到系統的其他部分告訴他們做某件事。如果系統的這一部分沒有運行(即在測試過程中),那麼這些屬性應該是完全惰性的。如果他們不是,那麼我傾向於看看你的單元測試項目,並確保你不會意外地運行諸如運行時安全框架之類的「實時」內容或其他東西