Luuk Krijnen
Luuk Krijnen

Reputation: 1192

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

Unittest Moq Setup where FakeCacheRepository is a derived type of 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.

Upvotes: 2

Views: 1129

Answers (2)

sloth
sloth

Reputation: 101042

In addition to what TomDoesCode already said:

To use Protected() the way you do, you'll have to use the generic version, since LoadFromContext returns a value (Person). Also, you'll have to pass the parameter:

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

Likewise, your Verify has to look like

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.

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.

Upvotes: 4

TomDoesCode
TomDoesCode

Reputation: 3681

The mock object personRepoMock that you setup doesn't appear to be being used by the FakeCacheRepository object 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. Externally, it shouldn't matter that FakeCacheRepository inherits from MyBaseClass, so just test the methods that FakeCacheRepository exposes.

If you want to share code between multiple classes, extract that code into a separate class - inheritance shouldn't be used for sharing code.

Upvotes: 3

Related Questions