2016-02-29 92 views
0

我有一個類負責構建用於導出的PPT幻燈片。爲了進行單元測試,我創建了一個接口,以便使用Moq進行模擬;迄今爲止都很棒。然而,當我試圖測試我的方法已被調用時,我遇到了困難。這是一個無效的方法,所以在這一點上,我只想知道該方法已被擊中。驗證是否使用Moq調用了無效方法

這裏是我的接口:

interface IPowerpointExporter 
{ 
    void AddSlides(int amount); 

    void setTitle(string title); 
} 

這是我的單元測試:

[TestMethod] 
public void testPPTObject() 
{ 
    var mockPPT = new Mock<IPowerpointExporter>(); 
    mockPPT.Setup(m => m.AddSlides(1)).Verifiable(); 
    mockPPT.Object.AddSlides(1); 
    mockPPT.VerifyAll(); 
} 

然而,當我來電話AddSlides()我得到一個GeneratorException。對此的解釋是我的IPowerpointExporter無法訪問。我有一種感覺,這是因爲我試圖在界面上調用一個方法,儘管我不確定,因爲此時我的對象在mockPPT.Object.AddSlides();

請注意,我也嘗試嘗試使用實際的對象而不是Interface.Object。這也給出了同樣的異常:

[TestMethod] 
public void testPPTObject() 
{ 
    var mockPPT = new Mock<IPowerpointExporter>(); 
    mockPPT.Setup(m => m.AddSlides(1)).Verifiable(); 

    ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object; 
    temp.AddSlides(1); 
    mockPPT.VerifyAll(); 
} 

使用起訂量我怎麼能確認我的方法被調用?我正在做的是正確的路線嗎?

+1

看來你正在測試你的模擬。您應該使用IPowerpointExporter測試代碼,並在那裏驗證(模擬)接口上的方法被稱爲 – andreasnico

回答

3

您可能會遇到此異常,因爲您的界面不是public,或者對Moq組件可見。請參閱this question來解決該問題。

如果這只是虛擬代碼來幫助您學習Moq,那麼請不要再閱讀。


但是,如果這是一個您認爲具有價值的實際測試,那麼您還有其他更基本的問題。在你的第一個例子中,你完全沒有辦法測試你的代碼!讓我們通過它,一行行:

var mockPPT = new Mock<IPowerpointExporter>(); 

您創建了IPowerpointExporter接口的模擬,到目前爲止,一切順利。

mockPPT.Setup(m => m.AddSlides(1)).Verifiable(); 

你告訴模擬期望調用它的AddSlide方法,用1參數,並且該方法可以驗證。到目前爲止沒有問題。

mockPPT.Object.AddSlides(1); 

但是,這裏是它脫軌的地方。你只是在你的模擬中調用該方法,就像你剛剛設置的那個一樣。 Object屬性是虛擬對象,它只能做它被設置的事情,而與你的實際實現沒有任何聯繫!

mockPPT.VerifyAll(); 

現在您驗證了您調用了所有可驗證的方法。你在這個測試中做的所有事情都證明了Moq的工作原理。你的代碼從未被觸及。

讓我們來看看改變的代碼在你的第二個例子,現在:

ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object; 
temp.AddSlides(1); 

以爲蒙上不會有任何效果。Object屬性只是一些代理(實際上是一種動態類型),由Moq生成,對於它正在嘲諷的接口的任何具體實現一無所知。

+0

爲了讓自己回到正確的軌道上,我該如何測試方法調用已被命中?只需創建一個ExportPowerPoint對象並調用AddSlides()方法就足以觸發VerifyAll()? – Novastorm

+0

你的第一個例子將做你想做的事(如果你修復了你的界面的可見性),但正如我所說的,除了學習Moq之外,它是一個毫無價值的測試。 –

0

發生此異常是因爲Moq不能訪問IPowerpointExporter接口。

你可以讓你IPowerpointExporter接口public和測試完美運行:

public interface IPowerpointExporter 
{ 
    void AddSlides(int amount); 

    void setTitle(string title); 
} 

.... 

[TestMethod] 
public void testPPTObject() 
{ 
    var mockPPT = new Mock<IPowerpointExporter>(); 
    mockPPT.Setup(m => m.AddSlides(1)).Verifiable(); 

    ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object; 
    temp.AddSlides(1); 
    mockPPT.VerifyAll(); 
} 

但是,當你需要做測試,以非公開的類型,可以使用InternalsVisibleTo屬性,在裝配,使各類可見起訂量。

[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")] 
+0

只是被帕特里克的答案毆打,將界面改爲公開是要走的路 – Novastorm