Question

Given a function like this:

public void AddItem( int itemId )
{
    if(itemId > 0)
    {
        Item i = new Item;
        i.ItemID = itemId
        i.DateChanged = DateTime.Today

        _repository.Items_Add(i);
        _repository.SaveChanges();
    }
}

Items_Add is a void function, which just checks entity framework to see if the passed Item needs to be added or attached/modified and does the appropriate job.

I want to use Moq to verify that "Items_Add" has been called, and with the expected object.

However, if I do this in my test:

[TestMethod]
public void Assert_AddItem_AddsValidItem
{
    Mock<IRepository> repMock = new Mock<IRepository>();

    MyViewModel mvm = new MyViewModel(repMock.Object);

    mvm.AddItem(1);

    Item testItem = new Item();
    testItem.ItemID = 1;
    testItem.DateChanged = DateTime.Today;

    repMock.Verify(m => m.Items_Add(testItem), Times.Once);
}

The test (not unexpectedly) fails claiming the function wasn't called as expected.

I assume this is because the object "testItem" that I create in the test is not the same as the object "i" created in AddItem, even though they're functionally identical.

If this is correct (please tell me if it's not), how do use Moq to verify that the function has been called and is working as expected? Given that Items_Add does not return anything, I'm unsure if I can use Moq to test it directly (with something equivalent to a "Returns" construct).

Was it helpful?

Solution

It.Is also allows for predicates, so you could do:

repMock.Verify(m => 
        m.Items_Add(It.Is<Item>(i => i.Id == testItem.Id)), Times.Once);

More generally, you could also make your test condition i.Equals(testItem) if you want to use the class's own equality comparison.

OTHER TIPS

If you're ok with "loosening up" your test a little, you can verify that the Items_Add method was called at all, with any Item:

repMock.Verify(m => m.Items_Add(It.IsAny<Item>()), Times.Once);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top