使用Moq ' It.Is '用于验证带有私有字段的构造函数参数/对象

本文关键字:字段 构造函数 对象 参数 验证 It Moq Is 用于 使用 | 更新日期: 2023-09-27 18:08:20

非常简单的例子:

public class Test
{
     private int _field;
   public Test(int field)
   {
     _field = field;
   }
}

现在我想检查方法是否被调用的参数类型为Test,它的构造函数参数等于5

_mock.Verify(x => x.Method(It.Is<Test>(constructor parameter equal to 5)));

使用Moq ' It.Is '用于验证带有私有字段的构造函数参数/对象

如果我理解正确的话,你有一个SUT (SystemUnderTest,下面),它调用了一个依赖项(IDependency),你用一个类(Test)的对象来模拟它,它不暴露一个公共getter属性。目前,您需要使用类似反射的hack来检查私有值,例如:

  public static TReturn GetPrivateField<TIn,TReturn>(TIn instance, 
                                                     string fieldName)
  {
     var fieldInfo = typeof(TIn).GetField(fieldName, BindingFlags.NonPublic | 
                             BindingFlags.Instance);
     return (fieldInfo != null)
               ? (TReturn)fieldInfo.GetValue(instance)
               : default(TReturn);
  }
  [Test]
  public void EnsureMethod()
  {
     var mock = new Mock<IDependency>();
     var sut = new SystemUnderTest(mock.Object);
     sut.DoSomethingGoodWithTest();
     mock.Verify(x => x.Method(It.Is<Test>(
                     t => GetPrivateField<Test, int>(t, "_field") == 5)));
  }

显然,这远非理想的,如果可能的话,可以重新考虑这种方法:

如果你不能改变Test._field的访问可见性,例如使用公共getter,但能够改变被测试类的设计,另一种选择是使用可注入工厂来创建Test类,例如使用IFactory.Create(int x)这样的方法。通过这种方式,您可以在测试期间模拟工厂,然后拦截Create调用并验证SUT确实使用所需的构造参数创建了Test对象。

不是测试构造函数,而是测试该属性是否设置了正确的值。看看是否可以用方法或属性或其他方式公开它。

如果你不能访问那个类来公开属性,你必须看看它是如何被使用的,也就是说,你要寻找用5或10或其他什么初始化this的副作用。