2011-03-09 54 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