Moq没有调用名为Finalize的方法

时间:2012-08-30 20:54:41

标签: c# unit-testing moq

好吧,我对此感到困惑。 Moq没有调用我的一个方法,但是验证时断言确实显示它正在调用我没有参数的所有其他方法。我甚至添加了以下内容:

.Throws<Exception>()

只是为了看看它是否会抛出,但仍然没有(但将其添加到其他方法中)。我知道正在使用的对象是我的模拟因为我添加了一个调用,该调用是在调用之后立即记录的。

方法名称为Finalize()。我怀疑方法的命名是问题,但我已经尝试了其他一切。

代码通过将main方法设为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();
}

此外,Moq是4.0.10827.0运行.Net 3.5

1 个答案:

答案 0 :(得分: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 I.10.5.2实例终结器

     

指定了终结器的行为   在分区I.指定了特定类型的finalize方法   通过覆盖System.Object中的虚拟方法Finalize。