在Moq中不调用方法

时间:2012-10-19 12:00:29

标签: c# unit-testing moq

我很想知道为什么不调用方法。 我创建了一个可以重现问题的小测试代码。

public interface ILoader
{
    IEnumerable<string> LoadAll();

    string LoadItem(int key);
}

public interface IStore
{
    IQueryable<string> Items { get; }
}

public abstract class StoreBase : IStore
{
    public void Load()
    {
        Items = LoadItems().ToArray().AsQueryable();
    }

    protected abstract IEnumerable<string> LoadItems();

    public IQueryable<string> Items { get; private set; }
}

public abstract class StoreBase2 : StoreBase
{
    private readonly ILoader _loader;

    protected StoreBase2(ILoader loader)
    {
        _loader = loader;
    }

    protected override IEnumerable<string> LoadItems()
    {
        return _loader.LoadAll();
    }
}

这里是测试的主体

Mock<ILoader> mockLoader = new Mock<ILoader>();
mockLoader.Setup(p => p.LoadAll()).Returns(() => Enumerable.Range(1, 10).Select(i => string.Format("Item: {0}", i)));
mockLoader.Setup(p => p.LoadItem(It.IsAny<int>())).Returns((int i) => string.Format("Item: {0}", i));

Mock<StoreBase2> mockStore = new Mock<StoreBase2>(mockLoader.Object);
mockStore.Object.Load();

mockLoader.Verify(p => p.LoadAll());

如果我介绍StoreBase2的具体实现(抱歉命名),并且我使用它而不是模拟基类,它可以工作。

public class StoreBaseImpl : StoreBase2
{
    public StoreBaseImpl(ILoader loader) : base(loader) {}
}

void MyTest() 
{
    Mock<ILoader> mockLoader = new Mock<ILoader>();
    mockLoader.Setup(p => p.LoadAll()).Returns(() => Enumerable.Range(1, 10).Select(i => string.Format("Item: {0}", i)));
    mockLoader.Setup(p => p.LoadItem(It.IsAny<int>())).Returns((int i) => string.Format("Item: {0}", i));

    var store = new StoreBaseImpl(mockLoader.Object);
    store.Load();
    mockLoader.Verify(p => p.LoadAll());
}   

我错过了什么吗?

编辑:在粘贴框中添加,以便更轻松地访问代码:http://pastebin.com/ggV20wAw

3 个答案:

答案 0 :(得分:2)

打开商店模拟基类的调用:

var mockStore = new Mock<StoreBase2>(mockLoader.Object) { CallBase = true };

此选项定义是否将调用基本成员虚拟实现,如果您未设置成员期望。因此,您无法为受保护的成员设置期望,只有启用此选项才会调用LoadItems()的{​​{1}}方法。否则StoreBase2不会被执行。

答案 1 :(得分:0)

您没有设置模拟Load(..)方法。

答案 2 :(得分:0)

我认为你必须使你的.Setups()可以这样验证:

mockLoader.Setup(p => p.LoadAll()).Returns("Blah").Verifiable();
mockLoader.Setup(p => p.LoadItem(It.IsAny<int>())).Returns("Blah").Verifiable();