Moq - 调用计数不匹配

时间:2015-07-30 14:19:23

标签: unit-testing moq

当我去验证使用某些参数调用方法的次数时,我似乎遇到了问题。我已粘贴下面的相关代码和单元测试。我的单元测试未能说module.exports = subscriptionsMixin; 的第一个更新根本没有被调用;而第二个被叫两次。我试过简化参数部分只看InventoryTransferItemTransaction;但仍然得到错误。调试代码表明正在传递正确的值。感觉我错过了一些东西,但不能完全指责它。

错误讯息:

transferType

单元测试:

Expected invocation on the mock once, but was 0 times: t => t.Update(It.Is<InventoryTransferItemTransaction>(args => (((((!(args.Created.IsNull()) && args.CreatedBy == User.GetNameFromContext()) && args.InventoryTransferItemId == 12) && !(args.Modified.IsNull())) && args.ModifiedBy == User.GetNameFromContext()) && args.Quantity == -10) && (Int32)args.TransactionType == 2))

Expected invocation on the mock once, but was 2 times: t => t.Update(It.Is<InventoryTransferItemTransaction>(args => (((((!(args.Created.IsNull()) && args.CreatedBy == User.GetNameFromContext()) && args.InventoryTransferItemId == 12) && !(args.Modified.IsNull())) && args.ModifiedBy == User.GetNameFromContext()) && args.Quantity == 0) && (Int32)args.TransactionType == 5))

RemoveTransferItem:

[Test]
public void CanRemoveTransferItem()
{
    const int TRANSFER_ITEM_ID = 12;
    const int QTY = 10;
    var inventoryTransferFactoryMock = new Mock<IInventoryTransferFactory>();
    inventoryTransferFactoryMock.Setup(t => t.GetTransferItem(TRANSFER_ITEM_ID))
                         .Returns(new InventoryTransferItem
                             {
                                 InventoryTransferItemId = TRANSFER_ITEM_ID,
                                 Quantity = QTY
                             });
    inventoryTransferFactoryMock.Setup(t => t.CreateInventoryTransferItemTransaction())
                                .Returns(new InventoryTransferItemTransaction());
    var inventoryTransferManager = new InventoryTransferManager(inventoryTransferFactoryMock.Object, null, null,
                                                                null, null);
    inventoryTransferManager.RemoveTransferItem(TRANSFER_ITEM_ID);
    inventoryTransferFactoryMock.Verify(t=>t.GetTransferItem(TRANSFER_ITEM_ID), Times.Once);
    inventoryTransferFactoryMock.Verify(
        t =>
        t.Update(
            It.Is<InventoryTransferItem>(
                args =>
                args.Quantity == 0 && args.ModifiedBy == User.GetNameFromContext() &&
                !args.Modified.IsNull() && !args.ClosedDate.IsNull())), Times.Once);
    inventoryTransferFactoryMock.Verify(t => t.CreateInventoryTransferItemTransaction(), Times.Exactly(2));
    inventoryTransferFactoryMock.Verify(
        t =>
        t.Update(It.Is<InventoryTransferItemTransaction>(
            args =>
            !args.Created.IsNull() && args.CreatedBy == User.GetNameFromContext() &&
            args.InventoryTransferItemId == TRANSFER_ITEM_ID &&
            !args.Modified.IsNull() && args.ModifiedBy == User.GetNameFromContext() &&
            args.Quantity == -QTY &&
            args.TransactionType == InventoryTransferTransactionType.TransferAdjusted)), Times.Once);
    inventoryTransferFactoryMock.Verify(
        t =>
        t.Update(It.Is<InventoryTransferItemTransaction>(
            args =>
            !args.Created.IsNull() && args.CreatedBy == User.GetNameFromContext() &&
            args.InventoryTransferItemId == TRANSFER_ITEM_ID &&
            !args.Modified.IsNull() && args.ModifiedBy == User.GetNameFromContext() &&
            args.Quantity == 0 &&
            args.TransactionType == InventoryTransferTransactionType.ClosedManually)), Times.Once);
}

LogTransferItemTransaction:

public void RemoveTransferItem(int inventoryTransferItemId)
{
    using (var trx = new TransactionWrapper())
    {
        var transferItem = inventoryTransferFactory.GetTransferItem(inventoryTransferItemId);
        transferItem.Modified = DateTime.Now;
        transferItem.ModifiedBy = User.GetNameFromContext();
        var originalQuantity = transferItem.Quantity;
        transferItem.Quantity = 0;
        transferItem.ClosedDate = DateTime.Now;
        inventoryTransferFactory.Update(transferItem);
        LogTransferItemTransaction(transferItem.InventoryTransferItemId, InventoryTransferTransactionType.TransferAdjusted, -originalQuantity);
        LogTransferItemTransaction(transferItem.InventoryTransferItemId, InventoryTransferTransactionType.ClosedManually, 0);
        trx.Complete();
    }
}

1 个答案:

答案 0 :(得分:1)

想出来。这条线是问题所在:

inventoryTransferFactoryMock.Setup(t => t.CreateInventoryTransferItemTransaction())
                                .Returns(new InventoryTransferItemTransaction());

它通过多次迭代返回相同的对象。因此,为什么第二次调用似乎在前0次被调用两次。

将其更改为固定测试:

inventoryTransferFactoryMock.Setup(t => t.CreateInventoryTransferItemTransaction())
                            .Returns(() => new InventoryTransferItemTransaction());