如何在Moq中验证对象类型参数

时间:2019-04-12 10:11:24

标签: c# unit-testing moq

我想使用匿名参数但具有已知属性的方法来测试方法的执行情况。

public interface IToTest
{
   void MethodToTest(object data);
}

这是我尝试实现的方法:

Mocker.Mock<IToTest>
   .Verify(x=>x.MethodToTest(
      It.Is<object>(
         obj=>obj.Equals(new { DataProperty = "Test"})
      )),
      Times.Once());

测试未通过。

我不想使用

It.IsAny<object>()

因为我知道预期的数据。

2 个答案:

答案 0 :(得分:1)

您当前的代表正在测试整个对象 obj是否等于匿名类型对象new { DataProperty = "Test"},这不太可能在测试您想要的对象。

您需要做的是检查:

1)obj具有您所期望名称的属性。

2)该属性具有您期望的值。

使用反射,您可以使用以下内容进行两项检查:

Mocker.Mock<IToTest>
   .Verify(x => x.MethodToTest(
       It.Is<object>(
           obj => 
               obj.GetType().GetProperty("PropertyOne") != null &&
               obj.GetType().GetProperty("PropertyOne").GetValue(obj).ToString() == "Test"
       )),
       Times.Once());

重要说明-如果属性不存在,请不要忘记对GetProperty()的结果进行NULL检查。

答案 1 :(得分:1)

您将需要在委托中使用反射进行比较,或者使用类似FluentAssertions的方法来减轻繁重的负担

例如

//...

var expected = new { 
    DataProperty = "Test" 
    //...known properties
};

Func<object, bool> match = _ => {
    _.Should().BeEquivalentTo(expected);
    return true;
};

Mocker.Mock<IToTest>
    .Verify(x =>
        x.MethodToTest(It.Is<object>(obj => match(obj))),
        Times.Once());

或者,您可以改为在回调中捕获对象参数,而只需使用流利的断言来断言捕获的参数。