我用一些抽象方法创建了一个抽象基类:
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);
}
现在我想检查我们是否调用了LoadFromContext,但是我收到错误: System.ArgumentException:Member FakeCacheRepository.LoadFromContext不存在
Unittest 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());
我做错了什么,有没有关于moq的好教程,以便更好地理解,而不必谷歌每个问题。
答案 0 :(得分:4)
除了TomDoesCode已经说过的话:
要按照您的方式使用Protected()
,您必须使用通用版本,因为LoadFromContext
会返回一个值(Person
)。此外,您必须传递参数:
personRepoMock.Protected().Setup<Person>("LoadFromContext", 14L);
同样,您的Verify
必须看起来像
personRepoMock.Protected().Verify<Person>("LoadFromContext", Times.Once(), 14L);
但即使你改变了,你的测试也行不通。您创建了FakeCacheRepository
的模拟,但随后在Load(14)
的新实例上调用FakeCacheRepository
,而不是在模拟上。
你应该后退一步,想一想你想要测试什么。如果您想测试FakeCacheRepository
是否从LoadFromContext
调用Load
,那么moq不适合该工作。
答案 1 :(得分:3)
您设置的模拟对象personRepoMock
似乎并未被FakeCacheRepository
对象person
使用。因此,您的设置和验证都没有使用。
但是,我不认为这是测试它的正确方法,我只是在没有嘲笑的情况下测试FakeCacheRepository
类。在外部,FakeCacheRepository
继承自MyBaseClass
并不重要,所以只需测试FakeCacheRepository
公开的方法。
如果要在多个类之间共享代码,请将该代码提取到单独的类中 - 继承不应该用于共享代码。