C# 验证是否使用moq调用了抽象方法

C# 验证是否使用moq调用了抽象方法,c#,moq,C#,Moq,我用一些抽象方法创建了一个抽象基类: public abstract class MyBaseClass<T> where T: class, IEntity { public T Load(long id) { //if in cache continue with cached value //else make use of protected abstract LoadFromContext } protected abstract

我用一些抽象方法创建了一个抽象基类:

public abstract class MyBaseClass<T> where T: class, IEntity
{

  public T Load(long id)
  {
     //if in cache continue with cached value 
     //else make use of protected abstract LoadFromContext
  }

  protected abstract T LoadFromContext(long id);
}
公共抽象类MyBaseClass,其中T:class,IEntity
{
公共T负载(长id)
{
//如果在缓存中,则继续使用缓存值
//否则,请使用受保护的抽象LoadFromContext
}
受保护的抽象T LoadFromContext(长id);
}
现在我想检查是否调用了LoadFromContext,但我得到一个错误:System.ArgumentException:Member FakeCacheRepository.LoadFromContext不存在

单元测试Moq设置,其中FakeCacheRepository是MyBaseClass的派生类型:

Mock<FakeCacheRepository> personRepoMock = new Mock<FakeCacheRepository>();
personRepoMock.Setup(x => x.Load(14)).Returns(new Person() { ID = 14, Name = "Developer14" });
personRepoMock.Protected().Setup("LoadFromContext");

var person = new FakeCacheRepository().Load(14);

Assert.AreEqual("Developer14", person.Name);
personRepoMock.Protected().Verify("LoadFromContext", Times.Once());
Mock personRepoMock=new Mock();
Setup(x=>x.Load(14)).Returns(newperson(){ID=14,Name=“Developer14”});
personRepoMock.Protected().Setup(“LoadFromContext”);
var person=new FakeCacheRepository().Load(14);
aresequal(“Developer14”,person.Name);
personRepoMock.Protected().Verify(“LoadFromContext”,Times.Once());

我做错了什么,有没有关于moq的好教程可以更好地理解,而不必搜索每个问题。

您设置的模拟对象
personRepoMock
似乎没有被
FakeCacheRepository
对象
人使用。因此,您的设置和验证未被使用

但是,我不认为这是正确的测试方法,我只会测试
FakeCacheRepository
类,而不进行模拟。从外部来看,
FakeCacheRepository
继承自
MyBaseClass
,这不重要,所以只需测试
FakeCacheRepository
公开的方法即可


如果要在多个类之间共享代码,请将该代码提取到单独的类中-继承不应用于共享代码。

除了TomDoesCode已经说过的内容外:

要以这种方式使用
Protected()
,必须使用通用版本,因为
LoadFromContext
返回一个值(
Person
)。此外,还必须传递参数:

personRepoMock.Protected().Setup<Person>("LoadFromContext", 14L);
但即使你改变了这一点,你的测试也不会起作用。您创建了一个模拟的
FakeCacheRepository
,但是在
FakeCacheRepository
的一个新实例上调用
Load(14)
,而不是在模拟上


你应该后退一步,想想你到底想测试什么。如果您想测试
FakeCacheRepository
是否从
Load
调用
LoadFromContext
,那么moq不是合适的工具。

嗨,Tom,我不想在这里讨论如何构建代码。我在哪里可以找到关于何时应该继承代码以及何时应该提取代码的指南。这里讨论的基类正式命名为“CachedRepositoryBase”……所有缓存内容都放在这里。只有特定于连接的东西被放置在继承的类中,而这些类仍然是缓存的存储库类(所以继承)。目前,这对我来说似乎是合法的。我没有任何特定的链接要发送,但在谷歌上快速搜索“编写可测试代码”这一短语,会找到很多可能感兴趣的文章。如果从Load调用“LoadFromContext”,我还有什么其他测试选项?除了手工调试。我不熟悉单元测试,但我看到了它的可能性和优势。如果你真的想测试,你可以创建一个
MyBaseClass
的子类,它只需在
LoadFromContext
中设置一个标志,调用
Load
后,检查该标志是否用一个简单的
Assert
设置。如果现在将代码中编写的缓存抽象出来,还可以测试在使用缓存的情况下是否未调用
LoadFromContext
personRepoMock.Protected().Verify<Person>("LoadFromContext", Times.Once(), 14L);