I have a method Apply()
that I’d like to write a unit test for:
public override MyList Apply(MyProduct product, MyState state)
{
if (product.Name == "Special Name")
{
state.MyProperty = 0;
return null;
}
else
{
return base.Apply(product, context, state);
}
}
MyProduct
inherits from another class, which inherits from BaseProduct
, which contains the Name
property:
public class BaseProduct
{
public string Name { get; set; }
}
I thought I could create a mock that returns “Special Name” for the Name
property to test this method, but I kept getting an exception stating that the getter is non-overrideable and cannot be used in setup/verification – I set it up like so:
var mock = new Mock<MyProduct>();
mock.SetupProperty(product => product.Name);
mock.SetupGet(product => product.Name).Returns("Special Name");
I’m having trouble mocking properties on MyProduct
in a way that allows me to pass an object to Apply()
that matches the method signature.
As an attempted solution, I created an interface for my test:
public class IBaseProduct {
string Name { get; set; }
}
In my test, I set the mock up like so:
var mock = new Mock<MyProduct>().As<IBaseProduct>();
mock.SetupProperty(product => product.Name);
mock.SetupGet(product => product.Name).Returns("Special Name");
I’m able to verify that mock.Object.Name
returns “Special Name,” but when I try to pass mock.Object
to Apply()
, I see that the class of the object is IBaseProduct
rather than MyProduct
.
Is this because MyProduct
(or BaseProduct
) is not declared to implement IBaseProduct
? I’d like to be able to write this test without changing MyProduct
or BaseProduct
.
I tried casting mock.Object
to MyProduct
like so:
Apply((MyProduct)mock.Object, state)
But when I do so, mock.Object.Name
then returns null
instead of “Special Name.”
How can I set this test up to mock MyProduct
and return the correct Name
without changing MyProduct
or BaseProduct
to implement IBaseProduct
?
2
In C# you can mock interface members (as you did with IProduct
) or abstract members.
I don’t quite understand why do you want to mock it in first place.
Mocking make sense where you have service/dependency of some sort, which is not available during test or is not practical to create it (so databases, services with some logic in it). You have simple POCO (plain old C# object), which does not have to be mocked.
Just set it explicitly:
var product = new Product() { Name = "Special Name" };
Apply(product, state);
2