2011-12-10 155 views
1

我的單元測試的方法說ABC()單元測試使用VS2010

myclass target = new myclass(); 
target.ABC(); 

反過來這ABC()方法調用來自不同類的另一種方法XYZ()之類anotherclass.XYZ()這XYZ()方法的輸入參數取決於來自文本框的值。

因爲在測試運行時沒有傳入文本框的值我在運行測試時收到空引用異常(我的意思是測試失敗,出現異常)。

類似的情況(另一人):從方法的查詢字符串像

HttpContext context 
id = context.request.querystring["id"] 

由於獲取的值id,在試運行這個ID值是零,我得到一個空referrence異常(我的意思是測試失敗除外)。

據我瞭解,這在邏輯上是正確的,因爲這是試運行,而不是實際的運行,但仍希望再次確認...

難道我做錯了什麼?

我的測試功能是否正確?

請建議。感謝你的幫助。

謝謝。

+0

您需要查看像Moq這樣的模擬框架,以便您可以使用模擬對象作爲依賴關係,並通過模擬框架控制依賴關係調用的結果。 –

+0

羅素,我知道,但你將如何嘲笑我的情況(我說過的一句話)......我不知道 – Rahul

+0

按照現在設計的方式正確地單元測試你的代碼是不可能的。爲了正確地進行單元測試,你需要抽象所有東西 - 通常是對接口進行編碼而不是具體的類,並將接口傳遞給需要依賴的任何東西。 –

回答

1

我不知道你的代碼是什麼樣的,但它可能需要重構一點點以允許單元測試。

舉例來說,如果你有這樣的代碼:

MyClass{ 

    private AnotherClass _another = new AnotherClass(); 

    public string ABC(){ 
    return _another.XYZ(); 
    } 
} 

public AnotherClass{ 
    //Context comes from somewhere... 
    public string XYZ(){ 
    return context.request.querystring["id"] 
    } 
} 

你會想改變它的東西是這樣的:

interface IAnotherClass{ 
    string XYZ(); 
} 

MyClass{ 
    private IAnotherClass _another = new AnotherClass(); 

    public MyClass(IAnotherClass anotherClass){ 
    _another = anotherClass; 
    } 

    public string ABC(){ 
    return _another.XYZ(); 
    } 
} 

public AnotherClass: IAnotherClass{ 
    //Context comes from somewhere... 
    public string XYZ(){ 
    return context.request.querystring["id"] 
    } 
} 

然後,您可以使用模擬框架嘲笑了像IceN一樣的其他類也有展示。至於HttpContext - 這會變得稍微複雜一點,但如果它只被AnotherClass使用,你不需要嘲笑它,因爲模擬對象只會返回你喜歡的任何東西。顯然,當你來測試AnotehrClass時,它就成了一個問題。如果你發現你確實需要嘲笑它,那麼有很多例子可以做 - 例如this之一。

1

您需要使用anotherclass的「not real」實例,但使用假冒XYZ實現的Mocked實例。

我將以Moq框架爲例。

Mock<IAnotherclass> anotherClassMock= new Mock<IAnotherclass>();//create mock instanse 
anotherClassMock.Setup(x=>x.XYZ);//add .Returns(something) if method XYZ returns some value 
myclass target = new myclass(anotherClassMock.Object);//create instance of object under test with fake instance of anotherClassMock 
target.ABC(); 
anotherClassMock.Verify(x=>x.XYZ);//verify that method XYZ is actualy been called 

首先,您需要提取類anotherclass的接口以創建模擬。在我的例子中,我使用了一個界面IAnotherclass

爲什麼我們這樣做?我們不包含類anotherclass的邏輯。我們假設它是正確的。所以我們從中抽象出來,只測試myclass的邏輯。而且,我們只用這種方法XYZ已被調用。