2011-03-09 52 views
12

我试图用起订量来测试,有一个“PARAMS”列表中的方法被调用的方法调用,但由于某种原因,这是失败的。该方法的签名是这样的:起订量 - 验证具有PARAMS值

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

然后在模拟设置我已经做了这样的事情做一个简单的从嘲笑集“删除/插入”:

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支持?

+0

什么版本的Moq? – 2011-03-09 14:46:51

+0

大会说4.0.0 – 2011-03-09 14:53:33

+0

啊,好的。我看到一个大约3和3.1的bug。 – 2011-03-09 14:55:01

回答

12

我很难复制这个。我觉得有一个错字在你的验证:

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应该是接口,而不是具体的类型?

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

要解决的是,我创建了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() { } 
} 

然后,我创建了一个测试夹具来验证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()); 
    } 
} 

这适用于我,所以我不认为问题是params值和Moq直接。我认为你应该退后一步,看看你是否真的对与Mock交互的类进行单元测试,或试图验证几种不同类型的综合用法。参数和表达树也有点味道。

+0

只是意识到验证没有被数组参数调用,但非常感谢花时间做这个测试。指定所有这一切有点麻烦,但是... – 2011-03-09 15:33:16

+1

我认为,如果它很难测试,那么它可能很难表达,而且很难理解。它值得考虑一下。 – 2011-03-09 16:04:31