I’m quite lost in trying to understand why a method doesn’t get invoked.
I created a little test code that reproduces the problem.
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();
}
}
end here is the body of the test
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());
If I introduce a concrete implementation of StoreBase2 (sorry for the naming), and I use it instead of mocking the base class, it works.
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());
}
Am I missing something?
EDIT: added on paste bin for easier access to the code: http://pastebin.com/ggV20wAw
Turn on calls to base class for your store mock:
This option defines whether base member virtual implementation will be called, if you didn’t setup expectations for member. Thus you can’t setup expectations for protected members, only turning on this option will call to
LoadItems()method ofStoreBase2. Otherwise_loader.LoadAll()is not executed.