C# Moq 拦截方法调用

Ric*_*ves 4 c# moq

我不确定我想做的事情是否可行。我有一个看起来像这样的界面:

public interface IObject
{
     void MethodA(ObjectA arg1);
     void MethodB(ObjectB arg1, ObjectC arg2);
     void MethodC(ObjectD arg1, ObjectE arg2);
}
Run Code Online (Sandbox Code Playgroud)

我有类似以下实现的东西:

public class ObjectImplementation : IObject
{
     public void MethodA(ObjectA arg1)
     {
          if(arg1.Something)
          {
               MethodB(new ObjectB(arg1), new ObjectC(arg1));
          }
          else
          {
               MethodC(new ObjectD(arg1), new ObjectE(arg1));
          }
     }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写一个单元测试来测试对 methodB 或 methodC 的调用是否是根据我的条件进行的。怎样才能实现这样的目标?

Alp*_*a75 5

您正在尝试模拟接口并验证该接口的实现。

您可以使方法 C 和 D 成为虚拟方法并在模拟中使用实现。

执行:

public class ObjectImplementation : IObject
{
    public void MethodA(ObjectA arg1)
    {
        if (arg1.Something)
        {
            MethodB(new ObjectB(arg1), new ObjectC(arg1));
        }
        else
        {
            MethodC(new ObjectD(arg1), new ObjectE(arg1));
        }
    }

    public virtual void MethodB(ObjectB arg1, ObjectC arg2)
    {

    }

    public virtual void MethodC(ObjectD arg1, ObjectE arg2)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

测试:

[Fact]
public void Test_WhenSomethingIsTrue_MethodB_Invoked_WithObjects_B_And_C()
{
    // Arrange
    Mock<ObjectImplementation> mockObject = new Mock<ObjectImplementation>();
    ObjectA arg = new ObjectA();
    arg.Something = true;

    // Act
    mockObject.Object.MethodA(arg);

    // Assert
    mockObject.Verify(o => o.MethodB(It.Is<ObjectB>(b=> b.Arg == arg), It.Is<ObjectC>(c => c.Arg == arg)));
}

[Fact]
public void Test_WhenSomethingIsFalse_MethodC_Invoked_WithObjects_D_And_E()
{
    // Arrange
    Mock<ObjectImplementation> mockObject = new Mock<ObjectImplementation>();
    ObjectA arg = new ObjectA();
    arg.Something = false;

    // Act
    mockObject.Object.MethodA(arg);

    // Assert
    mockObject.Verify(o => o.MethodC(It.Is<ObjectD>(d => d.Arg == arg), It.Is<ObjectE>(e => e.Arg == arg)));
}
Run Code Online (Sandbox Code Playgroud)