How to use Moq to test a method without return value?

This is my first question, so be kind! :)

What I'm trying to do is write some tests for the manager class, which during construction adds many new instances of the same element class to the list. When UpdateAllItems is called in this dispatcher class, it is assumed that it renames the list and calls Increment for each individual item.

The manager class is my code, but one element class is wrong, I cannot change it.

I am using NUnit as a testing framework and starting to work with Moq. Since the manager class uses a single element class, I would think that I need to use Moq, so I only test the manager, not the individual element.

How to write tests for my UpdateAllItems method? (Technically, I must first write the tests that I know).

Here is a sample code that gives a general idea of ​​what I'm working with ...

public class SingleItem_CodeCantBeModified
{
    public int CurrentValue { get; private set; }

    public SingleItem_CodeCantBeModified(int startValue)
    {
        CurrentValue = startValue;
    }

    public void Increment()
    {
        CurrentValue++;
    }
}

public class SingleItemManager
{
    List<SingleItem_CodeCantBeModified> items = new List<SingleItem_CodeCantBeModified>();

    public SingleItemManager()
    {
        items.Add(new SingleItem_CodeCantBeModified(100));
        items.Add(new SingleItem_CodeCantBeModified(200));
    }

    public void UpdateAllItems()
    {
        items.ForEach(item => item.Increment());
    }
}

Thanks in advance for your help!

+5
source share
4 answers

The simple answer is: you cannot. The method that UpdateAllItemscalls ( Increment()) is not virtual, so you cannot mock it.

Your options, as I see it, are as follows:

  • Do not test UpdateAllItemsat all. Its implementation is trivial, therefore it is a variant of consideration (although not ideal).
  • SingleItem_CodeCantBeModified . , unit test, .
  • ISingleItem SingleItemAdapter : ISingleItem, SingleItem_CodeCantBeModified . SingleItemManager ISingleItem s, mock ISingleItem . ( , , SingleItem_CodeCantBeModified, .)

, . , , .

+5

( List<Item>). , ? :.

public SingleItemManager()
{
    items.Add(ItemRepository.Get(100));
    items.Add(ItemRepository.Get(200));
}

( ):

int i = 0;

var itemMock = new Mock<Item>();
itemMock.Setup(i => i.Increment()).Callback(() => i++);

var repositoryMock = new Moc<ItemRepository>();
repositoryMock.Setup(r => r.Get(It.IsAny<int>()).Returns(itemMock.Object);

var manager = new SingleItemManager();
manager.UpdateAllItems();

Assert.AreEqual(i, 1);
+1

, .

  • SingleItem_CodeCantBeModified
  • IItem
  • SingleItemManager IItem SingleItem_CodeCantBeModified

Increment - ( , , ), partial mocking.

0

, SingleItem_CodeCantBeModified ( , ), () factory, .

In your test, you create a factory layout to go to your Manager class, then you can control which methods are called on this mocked object.

Although this would be more related to testing the internal components of the system, rather than to by-products. What interface does the manager implement? If he does not prove himself externally, what results do you experience?

-1
source

All Articles