1

OK、私はこの時点で困惑しています。Moq は私の 1 つのメソッドを呼び出していませんが、verify のアサートは、パラメーターなしではない他のすべてのメソッドを呼び出していることを示しています。私は以下を追加しました:

.Throws<Exception>()

それがスローされるかどうかを確認するだけで、まだ何もありません(ただし、他のメソッドに追加すると機能します)。使用されているオブジェクトが私のモックであることはわかっています。これは、ログに記録されていない呼び出しの直後に IS という呼び出しを追加したためです。

メソッド名は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は.Net 3.5に対して実行されている4.0.10827.0です

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()
    {
    }
}

これらの2つのメソッドは同じものであるため、このコードはコンパイルされなくなります。トリッキー、え?:)

ECMA-335にも記載されています。

II.10.5.2インスタンスファイナライザー

ファイナライザーの動作は、パーティションIで指定されます。特定のタイプのfinalizeメソッドは、System.Objectの仮想メソッドFinalizeをオーバーライドすることによって指定されます。

于 2012-08-30T23:10:27.430 に答える