My problem is that I want to stub a property in my abstract class, because my class in test uses that property. I'm currently using latest version of Moq.
My abstract class looks like this:
public abstract class BaseService
{
protected IDrawingSystemUow Uow { get; set; }
}
And my class in test looks like this:
public class UserService : BaseService, IUserService
{
public bool UserExists(Model model)
{
var user = this.Uow.Users.Find(model.Id);
if(user == null) { return false; }
reurn true;
}
}
I can't figure out how I can stub the Uow
property. Does anybody have any clue? Or is my design that bad that I need to move to Uow
property to my class in test?
The answer is: always test only concrete classes; don't test abstract classes directly . The reason is that abstract classes are implementation details. From the client perspective, it doesn't matter how Student or Professor implement their GetSignature() methods.
An abstract class cannot be inherited by structures. It can contain constructors or destructors. It can implement functions with non-Abstract methods. It cannot support multiple inheritances.
If the Child class is unable to provide implementation to all abstract methods of the Parent class then we should declare that Child class as abstract so that the next level Child class should provide implementation to the remaining abstract method.
An abstract class defines the identity of a class. An interface can inherit multiple interfaces but cannot inherit a class. An abstract class can inherit a class and multiple interfaces. An interface cannot declare constructors or destructors.
Your current setup won't work for one simple reason - Uow
property is non-overridable and Moq's job is done at this point. Cannot override, cannot mock.
Easiest solution is to simply make that property overridable. Change your base class definition to:
public abstract class BaseService
{
protected virtual IDrawingSystemUow Uow { get; set; }
}
Now you can use Moq's protected feature (this requires you to include using Moq.Protected
namespace in your test class):
// at the top of the file
using Moq.Protected;
// ...
var drawingSystemStub = new Mock<IDrawingSystemUow>();
var testedClass = new Mock<UserService>();
testedClass
.Protected()
.Setup<IDrawingSystemUow>("Uow")
.Returns(drawingSystemStub.Object);
// setup drawingSystemStub as any other stub
// exercise test
var result = testedClass.Object.UserExists(...);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With