1

好吧,我在这一点上感到困惑。Moq 没有调用我的一个方法,但验证上的断言确实表明它正在调用我所有其他非无参数的方法。我什至添加了以下内容:

.Throws<Exception>()

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

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

代码通过公开主要方法简化为最简单的解决方案后:

  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 运行

4

1 回答 1

3

将您的方法重命名为Finalize. 如果我复制/粘贴您的代码并重命名该方法,它就会开始正常工作。

它还会生成编译器警告 CS0465,应避免使用。

这不起作用的原因是它Finalize实际上是类析构函数的保留名称。如果您编写此 C# 代码:

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

Finalize()编译器实际上在 IL 代码中命名了析构函数:

.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 中指定。特定类型的终结方法是通过覆盖 System.Object 中的虚拟方法 Finalize 来指定的。

于 2012-08-30T23:10:27.430 回答