c# - Moq - 验证具有参数值的方法调用

标签 c# .net unit-testing moq

我正在尝试使用 Moq 测试调用具有“params”列表的方法,但由于某种原因,这失败了。方法签名是这样的:

void AttachAsModifiedToOrders(IOrder order, params 
       Expression<Func<IOrder, object>>[] modifiedProperties);

然后在 Mock 设置中我做了类似这样的事情来从模拟集合中做一个简单的“删除/插入”:

MockEntities.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<DataAccess.Order>()))
    .Callback<IOrder, Expression<Func<IOrder, object>>[]>((order, expr) => 
      { Orders.Remove(Orders.Where(o => o.Id== order.Id).First()); 
      Orders.Add((DataAccess.Order)order); });

最后,验证:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), 
     It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1));

我已经检查过,代码执行正常并且调用了方法(模拟的方法),但验证失败。我错过了什么吗?或者只是 Moq 不支持此“params”调用?

最佳答案

我很难复制这个。我认为您的验证中有错字:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1));

应该是:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Exactly(1));

我也想知道第一个 It.IsAny 是否应该是接口(interface)而不是具体类型?

但是,这是对某些功能的过于复杂的测试,并且代码示例缺少一些部分,例如 DataAccess 类型或类实例(不确定?)、Order 和 Orders。

为了解决这个问题,我创建了 IOrder 接口(interface)和一个使用该接口(interface)的操纵器对象,它有点荒谬,但它驱动了测试:

public interface IOrder
{
    void AttachAsModifiedToOrders(IOrder order, params Expression<Func<IOrder, object[]>>[] modifiedProperties);

}

public class Manipulator
{
    public Manipulator(IOrder order)
    {
        Expression<Func<IOrder, object[]>> exp = o => new object[0];
        order.AttachAsModifiedToOrders(order, exp);
    }

    public void DoStuff() { }
}

然后我创建了一个测试夹具来验证参数 arg:

[TestFixture]
public class Tester
{
    [Test]
    public void Test()
    {
        var order = new Mock<IOrder>();
        order.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<IOrder>()));

        var manipulator = new Manipulator(order.Object);
        manipulator.DoStuff();

        order.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<IOrder>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Once());
    }
}

这对我有用,所以我认为问题不在于参数值和直接起订量。我确实认为您最好退后一步,看看您是否真的在对与 Mock 交互的类进行单元测试,或者尝试验证几种不同类型的集成用法。参数和表达式树也有点味道。

关于c# - Moq - 验证具有参数值的方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5246854/

相关文章:

c# - 从事件中删除空处理程序有任何副作用吗?

c# - 隐藏派生类

c# - 使用 Paypal 的 IPN、C# 连接数据库时出现问题

django - 使用 FileField 对 Django 表单进行单元测试

c# - 确定一个 int 值是否在数组中存在一次

c# - 操纵 setter 以避免 null

c# - 如何在 xamarin 中添加 System.Drawing?

c# - 加密安全的 XML 比较器

java - 此处检测到错位的参数匹配器。您不能在 Mockito 中的验证或 stub 之外使用参数匹配器

unit-testing - 使用mockito模拟外部服务