C# 方法isn';最小起订量中的t
我很难理解为什么一个方法不能被调用。 我创建了一个小测试代码来重现这个问题C# 方法isn';最小起订量中的t,c#,unit-testing,moq,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 : ISt
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();
}
}
公共接口ILoader
{
IEnumerable LoadAll();
字符串加载项(int键);
}
公共接口晶体管
{
IQueryable项{get;}
}
公共抽象类库:IStore
{
公共空荷载()
{
Items=LoadItems().ToArray().AsQueryable();
}
受保护的抽象IEnumerable LoadItems();
公共IQueryable项{get;private set;}
}
公共抽象类StoreBase 2:StoreBase
{
专用只读ILoader\u加载程序;
受保护的StoreBase2(ILoader加载程序)
{
_装载机=装载机;
}
受保护的覆盖IEnumerable LoadItems()
{
返回_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());
Mock mockLoader=new Mock();
mockLoader.Setup(p=>p.LoadAll())。返回(()=>Enumerable.Range(1,10)。选择(i=>string.Format(“项:{0}”,i));
Setup(p=>p.LoadItem(It.IsAny())。返回((inti)=>string.Format(“Item:{0}”,i));
Mock mockStore=新的Mock(mockLoader.Object);
mockStore.Object.Load();
验证(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());
}
公共类StoreBaseImpl:StoreBase2
{
public StoreBaseImpl(ILoader装入器):基本(装入器){}
}
void MyTest()
{
Mock mockLoader=new Mock();
mockLoader.Setup(p=>p.LoadAll())。返回(()=>Enumerable.Range(1,10)。选择(i=>string.Format(“项:{0}”,i));
Setup(p=>p.LoadItem(It.IsAny())。返回((inti)=>string.Format(“Item:{0}”,i));
var store=newstorebaseimpl(mockLoader.Object);
store.Load();
验证(p=>p.LoadAll());
}
我错过什么了吗
编辑:添加到粘贴箱以便于访问代码:您没有设置模拟加载(..)方法。我认为您必须使您的.Setups()可验证,如下所示:
mockLoader.Setup(p => p.LoadAll()).Returns("Blah").Verifiable();
mockLoader.Setup(p => p.LoadItem(It.IsAny<int>())).Returns("Blah").Verifiable();
mockLoader.Setup(p=>p.LoadAll())。返回(“Blah”).Verifiable();
mockLoader.Setup(p=>p.LoadItem(It.IsAny())。返回(“Blah”).Verifiable();
为商店模拟打开对基类的调用:
var mockStore = new Mock<StoreBase2>(mockLoader.Object) { CallBase = true };
var mockStore=newmock(mockLoader.Object){CallBase=true};
此选项定义如果未设置成员的期望值,是否调用基本成员虚拟实现。因此,您无法设置受保护成员的期望值,只有启用此选项才能调用
StoreBase2
的LoadItems()
方法。否则将不执行\u loader.LoadAll()
。为什么要设置它?它的基类提供的实现对我来说很好。顺便说一句,它不是“可设置的”,因为它不是虚拟的。如果您将mockLoader的行为设置为strict怎么办:Mock mockLoader=new Mock(MockBehavior.strict);这就成功了!:)无论如何,我对mockLoader设定了期望,这对我来说已经足够了。