简体   繁体   English

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

[英]Moq - Verify method call that has a params value

I'm trying to test with Moq that a method that has a "params" list is called, but for some reason this is failing. 我试图用Moq测试一个有“params”列表的方法被调用,但由于某种原因,这是失败的。 The method signature is something like this : 方法签名是这样的:

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

Then in the Mock setup i've done something like this to do a simple "remove / insert" from the mocked collection : 然后在模拟设置中,我做了类似的事情,从模拟集合中做一个简单的“删除/插入”:

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); });

Finally, the verification : 最后,验证:

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

I've checked, and the code executes ok and the method is called (the mocked one), but the verification is failing. 我已经检查过,代码执行正常并且调用了方法(模拟的方法),但验证失败了。 am i missing something? 我错过了什么吗? or is it just that this "params" call is not supported by Moq? 或者仅仅是Moq不支持这种“params”呼叫?

I had difficulty replicating this. 我很难复制这个。 I think there's a typo in your verify: 我认为您的验证中存在拼写错误:

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

Should be: 应该:

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

I also wonder if the first It.IsAny should be the interface and not the concrete type? 我也想知道第一个It.IsAny应该是接口而不是具体类型?

However, this is a overly-complicated test of some bit of functionality, and the code sample is missing a few pieces, like the DataAccess type or class instance (not sure?), Order, and Orders. 但是,这是对某些功能的过于复杂的测试,并且代码示例缺少一些部分,例如DataAccess类型或类实例(不确定?),Order和Orders。

To work around that, I created the IOrder interface and a manipulator object that uses the interface, its a bit nonsensical, but it drives the test: 为了解决这个问题,我创建了IOrder接口和一个使用该接口的操纵器对象,它有点荒谬,但它驱动测试:

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

I then created a test fixture to validate the params arg: 然后我创建了一个测试夹具来验证params 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());
    }
}

This works for me, so I don't think the problem is the params value and Moq directly. 这对我有用,所以我不认为问题是params值和Moq直接。 I do think you'd be well off to take a step back and see if you are really unit testing the class that interacts with the Mock, or trying to verify integrated usages of a couple different types. 我认为你退后一步,看看你是否真的对与模拟交互的类进行单元测试,或者尝试验证几种不同类型的集成用法。 The params and expression tree is a bit of a smell also. 参数和表达树也有点气味。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM