简体   繁体   English

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

[英]Verify if an abstract method is called using moq

I have created an abstract baseclass with some abstract methods: 我用一些抽象方法创建了一个抽象基类:

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);
}

now I want to check if the LoadFromContext us called but I get an error : System.ArgumentException: Member FakeCacheRepository.LoadFromContext does not exist 现在我想检查我们是否调用了LoadFromContext,但是我收到一个错误: System.ArgumentException:Member FakeCacheRepository.LoadFromContext不存在

Unittest Moq Setup where FakeCacheRepository is a derived type of MyBaseClass: Unittest Moq Setup其中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());

What an I doing wrong and are there any good tutorials about moq for a better understanding without having to Google each individual question. 我做错了什么,有没有关于moq的好教程,以便更好地理解,而不必谷歌每个问题。

In addition to what TomDoesCode already said: 除了TomDoesCode已经说过的话:

To use Protected() the way you do, you'll have to use the generic version, since LoadFromContext returns a value ( Person ). 要按照您的方式使用Protected() ,您必须使用通用版本,因为LoadFromContext返回一个值( Person )。 Also, you'll have to pass the parameter: 此外,您必须传递参数:

personRepoMock.Protected().Setup<Person>("LoadFromContext", 14L);

Likewise, your Verify has to look like 同样,您的Verify必须如此

personRepoMock.Protected().Verify<Person>("LoadFromContext", Times.Once(), 14L);

But even if you would change that, your test would not work. 但即使你改变了,你的测试也行不通。 You create a mock of FakeCacheRepository , but then call Load(14) on a new instance of FakeCacheRepository , not on the mock. 您创建了FakeCacheRepository的模拟,但随后在FakeCacheRepository的新实例上调用Load(14) ,而不是在模拟上。

You should take a step back and think about what exactly you want to test. 你应该退后一步,想一想你想要测试什么。 If you want to test if FakeCacheRepository calls LoadFromContext from Load , then moq is not the right tool for the job. 如果要测试FakeCacheRepository是否从Load调用LoadFromContext ,则moq不是该作业的正确工具。

The mock object personRepoMock that you setup doesn't appear to be being used by the FakeCacheRepository object person . 您设置的模拟对象personRepoMock似乎没有被FakeCacheRepository对象person So your setup and verify aren't used. 因此,不使用您的设置和验证。

However, I don't think that this is the correct approach for testing this, I would just test the FakeCacheRepository class without mocking. 但是,我不认为这是测试它的正确方法,我只是在没有FakeCacheRepository情况下测试FakeCacheRepository类。 Externally, it shouldn't matter that FakeCacheRepository inherits from MyBaseClass , so just test the methods that FakeCacheRepository exposes. 在外部, FakeCacheRepository继承MyBaseClass并不重要,所以只需测试FakeCacheRepository公开的方法。

If you want to share code between multiple classes, extract that code into a separate class - inheritance shouldn't be used for sharing code. 如果要在多个类之间共享代码,请将该代码提取到单独的类中 - 继承不应用于共享代码。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM