使用最小起订量验证是否调用了抽象方法
Verify if an abstract method is called using 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 T LoadFromContext(long id);
}
现在我想检查我们是否调用了 LoadFromContext 但出现错误:System.ArgumentException: 成员 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());
我哪里做错了?是否有任何关于最小起订量的好教程可以更好地理解,而不必 Google 每个单独的问题。
您设置的模拟对象 personRepoMock
似乎没有被 FakeCacheRepository
对象 person
使用。所以你的设置和验证没有被使用。
但是,我认为这不是测试它的正确方法,我只是测试 FakeCacheRepository
class 而不进行模拟。在外部,FakeCacheRepository
继承自 MyBaseClass
并不重要,因此只需测试 FakeCacheRepository
公开的方法即可。
如果您想在多个 class 之间共享代码,请将该代码提取到一个单独的 class - 继承不应用于共享代码。
除了 TomDoesCode 已经说过的:
要按照您的方式使用 Protected()
,您必须使用通用版本,因为 LoadFromContext
returns 是一个值 (Person
)。此外,您必须传递参数:
personRepoMock.Protected().Setup<Person>("LoadFromContext", 14L);
同样,您的 Verify
必须看起来像
personRepoMock.Protected().Verify<Person>("LoadFromContext", Times.Once(), 14L);
但即使您更改它,您的测试也不会成功。您创建了 FakeCacheRepository
的模拟,但随后在 FakeCacheRepository
的新实例上调用 Load(14)
,而不是在模拟上调用 Load(14)
。
你应该退后一步,想想你到底想测试什么。如果您想测试 FakeCacheRepository
是否从 Load
调用 LoadFromContext
,那么最小起订量不是完成这项工作的正确工具。
我用一些抽象方法创建了一个抽象基类:
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: 成员 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());
我哪里做错了?是否有任何关于最小起订量的好教程可以更好地理解,而不必 Google 每个单独的问题。
您设置的模拟对象 personRepoMock
似乎没有被 FakeCacheRepository
对象 person
使用。所以你的设置和验证没有被使用。
但是,我认为这不是测试它的正确方法,我只是测试 FakeCacheRepository
class 而不进行模拟。在外部,FakeCacheRepository
继承自 MyBaseClass
并不重要,因此只需测试 FakeCacheRepository
公开的方法即可。
如果您想在多个 class 之间共享代码,请将该代码提取到一个单独的 class - 继承不应用于共享代码。
除了 TomDoesCode 已经说过的:
要按照您的方式使用 Protected()
,您必须使用通用版本,因为 LoadFromContext
returns 是一个值 (Person
)。此外,您必须传递参数:
personRepoMock.Protected().Setup<Person>("LoadFromContext", 14L);
同样,您的 Verify
必须看起来像
personRepoMock.Protected().Verify<Person>("LoadFromContext", Times.Once(), 14L);
但即使您更改它,您的测试也不会成功。您创建了 FakeCacheRepository
的模拟,但随后在 FakeCacheRepository
的新实例上调用 Load(14)
,而不是在模拟上调用 Load(14)
。
你应该退后一步,想想你到底想测试什么。如果您想测试 FakeCacheRepository
是否从 Load
调用 LoadFromContext
,那么最小起订量不是完成这项工作的正确工具。