Moq - Non-overridable members may not be used in setup / verification expressions
Moq creates an implementation of the mocked type. If the type is an interface, it creates a class that implements the interface. If the type is a class, it creates an inherited class, and the members of that inherited class call the base class. But in order to do that it has to override the members. If a class has members that can't be overridden (they aren't virtual, abstract) then Moq can't override them to add its own behaviors.
In this case there's no need to mock PagingOptions
because it's easy to use a real one. Instead of this:
var mockPagingOptions = new Mock<PagingOptions>();
mockPagingOptions.Setup(po => po.Limit).Returns(25);
mockPagingOptions.Setup(po => po.Offset).Returns(0);
Do this:
var pagingOptions = new PagingOptions { Limit = 25, Offset = 0 };
How do we determine whether or not to mock something? Generally speaking, we mock something if we don't want to include the concrete runtime implementation in our test. We want to test one class not both at the same time.
But in this case PagingOptions
is just a class that holds some data. There's really no point in mocking it. It's just as easy to use the real thing.
I had the same error, but in my case I was trying to mock the class itself and not its interface:
// Mock<SendMailBLL> sendMailBLLMock = new Mock<SendMailBLL>(); // Wrong, causes error.
Mock<ISendMailBLL> sendMailBLLMock = new Mock<ISendMailBLL>(); // This works.
sendMailBLLMock.Setup(x =>
x.InsertEmailLog(
It.IsAny<List<EmailRecipient>>(),
It.IsAny<List<EmailAttachment>>(),
It.IsAny<string>()));
I want to improve Scott's answer and give a general answer
If the type is a class, it creates an inherited class, and the members of that inherited class call the base class. But in order to do that it has to override the members. If a class has members that can't be overridden (they aren't virtual, abstract) then Moq can't override them to add its own behaviors.
In my situation i had to make the prop virtual. So answer to your class code is:
public class PagingOptions {
[Range (1, 99999, ErrorMessage = "Offset must be greater than 0.")]
public virtual int? Offset { get; set; }
[Range (1, 100, ErrorMessage = "Limit must be greater than 0 and less than 100.")]
public virtual int? Limit { get; set; }
public PagingOptions Replace (PagingOptions newer) {
return new PagingOptions {
Offset = newer.Offset ?? Offset,
Limit = newer.Limit ?? Limit
};
}
}
use same:
var mockPagingOptions = new Mock<PagingOptions>();
mockPagingOptions.Setup(po => po.Limit).Returns(25);
mockPagingOptions.Setup(po => po.Offset).Returns(0);