如何使用Moq测试没有返回值的方法?

Fra*_*hia 5 .net c# unit-testing moq mocking

这是我的第一个问题所以请善待!:)

我想要做的是为管理器类编写一些测试,在构造期间将单个项类的许多新实例添加到列表中.在此管理器类中调用UpdateAllItems时,目的是迭代列表并对每个项目调用Increment.

经理类是我的代码,但单项类不是这样我无法修改它.

我使用NUnit作为测试框架,并开始使用Moq.因为经理类使用单项类我认为我需要使用Moq所以我只测试经理,而不是单项.

如何为UpdateAllItems方法编写测试?(从技术上讲,我应该首先编写我知道的测试).

这里有一些示例代码,可以大致了解我正在使用的内容......

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

在此先感谢您的帮助!

Joe*_*ite 5

简单的答案是,你做不到.该方法UpdateAllItems调用(Increment())是非虚拟的,所以你不能嘲笑它.

我认为你的选择是:

  • 根本不要测试UpdateAllItems.它的实现是微不足道的,所以这是一个考虑的选择(虽然不是理想的).
  • SingleItem_CodeCantBeModified在测试中创建实例.纯粹主义者会说你现在不再进行单元测试了,但它仍然是一个有用的测试.
  • 添加一个ISingleItem接口,以及一个SingleItemAdapter : ISingleItem保留对a的引用SingleItem_CodeCantBeModified并转发调用的类.然后你可以写s SingleItemManager操作ISingleItems,你可以ISingleItem在测试中自由传递模拟.(根据系统的设置方式,您甚至可以下载SingleItem_CodeCantBeModified,在后代上实现接口,并使用这些对象而不是编写适配器.)

最后一个选项为您提供了最多选择,但代价是复杂性.选择最适合您要完成的选项.