2012-08-30 58 views
1

好的,我對此感到莫名其妙。 Moq沒有調用我的一個方法,但驗證的斷言確實表明它調用了所有其他非參數方法。我甚至已經添加了以下內容:Moq沒有調用方法命名爲Finalize

.Throws<Exception>() 

只是爲了看看它甚至會拋出,並且仍然沒有(但將它添加到其他方法的工作原理)。我知道所使用的對象是我的模擬,因爲我添加了一個呼叫,該呼叫在呼叫之後立即被記錄。

方法名稱是Finalize()。我懷疑該方法的命名是否是問題,但我嘗試了其他一切。

代碼通過使主要方法public簡化到最簡單的解決方案後:

var asyncRecognizerMock = new Mock<AsyncRecognizer>(); 
    var asyncRecognizerFactoryMock = new Mock<AsyncRecognizerFactory>(); 
    var trainerMock = new Mock<Trainer>(); 
    trainerMock.Setup(trainer => trainer.Finalize()).Verifiable(); 
    var trainerDataRepository = new TrainerDataRepository(asyncRecognizerFactoryMock.Object, asyncRecognizerMock.Object); 

    trainerDataRepository.FinalizeTrainer(trainerMock.Object); 

    trainerMock.Verify(trainer => trainer.Finalize(), Times.Once()); 

我的方法現在是:

public void FinalizeTrainer(Trainer wordTrainer) 
{ 
    wordTrainer.Finalize(); 
} 

而且,起訂量是4.0.10827.0進行鍼對.NET 3.5

運行
+0

呃......你可能想要展示一些更多的代碼 - 只是說明Moq沒有做你期望的事情,並沒有太多的合作。 – driis

+0

你想要我發佈什麼樣的代碼?我知道我正在調用它,因爲如果我驗證其他方法,相同的EXACT代碼將起作用。 –

+0

那麼,Moq適用於無參數方法,我知道一個事實 - 所以你可能會錯過一些東西。你如何設置Moq,以及你對Moq'ed物體的確切呼叫是什麼? – driis

回答

3

將您的方法重命名爲Finalize以外的其他方法。如果我複製/粘貼代碼並重命名該方法,它會開始正常工作。

它也生成compiler warning CS0465,應該避免。

這不起作用的原因是Finalize實際上是類析構函數的保留名稱。如果你寫C#代碼:

public class Trainer 
{ 
    ~Trainer() 
    { 
     int x = 1; 
    } 
} 

編譯器實際名稱的IL代碼析構函數Finalize()

.method family hidebysig virtual instance void 
     Finalize() cil managed 
{ 
    // Code size  16 (0x10) 
    .maxstack 1 
    .locals init ([0] int32 x) 
    .try 
    { 
    IL_0000: nop 
    IL_0001: ldc.i4.1 
    IL_0002: stloc.0 
    IL_0003: nop 
    IL_0004: leave.s IL_000e 
    } // end .try 
    finally 
    { 
    IL_0006: ldarg.0 
    IL_0007: call  instance void [mscorlib]System.Object::Finalize() 
    IL_000c: nop 
    IL_000d: endfinally 
    } // end handler 
    IL_000e: nop 
    IL_000f: ret 
} // end of method Trainer::Finalize 

事實上,如果你嘗試添加兩個析構函數和一個finalize方法:

public class Trainer 
{ 
    ~Trainer() 
    { 
    } 

    public virtual Finalize() 
    { 
    } 
} 

此代碼將不再編譯,因爲這兩個方法是相同的東西。詭計,呃? :)

它也是在指出ECMA-335:

我I.10.5.2實例終結

終結的行爲在分區一對finalize方法指定 通過重寫System.Object中的虛擬方法Finalize來指定特定類型 。

+0

我有一個理論是問題...然而,改變這個名字是一個可怕的痛苦,因爲它是來自C++ interop的傳統 - 這也解釋了爲什麼我沒有在我的代碼中得到編譯器警告。我將改變標題以反映這一點,也許稍後再幫助其他人。 –