Say i have this example code:
interface IBase {
int BaseProperty { get; }
}
interface IDerived : IBase {
int DerivedProperty { get; }
}
and i like to write mocks for both interfaces.
Base mock is easy:
class BaseMock : Mock<IBase> {
public int BaseProperty { get; set; } = 42;
public BaseMock() {
SetupGet(o => o.BaseProperty).Returns(BaseProperty);
}
}
but im not sure how to correctly write derived mock:
class DerivedMock : Mock<IDerived> {
public int BaseProperty { get; set; } = 42;
public int DerivedProperty { get; set; } = 73;
public DerivedMock() {
// setups related to IBase
SetupGet(o => o.BaseProperty).Returns(BaseProperty);
// setups related to IDerived
SetupGet(o => o.DerivedProperty).Returns(DerivedProperty);
}
}
this implementation will work as expected, but im forced to copy bassically whole content of BaseMock
class here and that is not DRY ...
ideally i would like to inherit DerivedMock
from BaseMock
, but then setups related to IDerived
would not compile (o
is IBase
and i it to be IDerived
)...
I appreciate any kick in the right direction :)
CodePudding user response:
Rafał Rutkowski kicked me to right direction and i ended up with this code for anyone else interested:
interface IBase {
int BaseProperty { get; }
}
interface IDerived : IBase {
int DerivedProperty { get; }
}
class BaseMock : Mock<IBase>, IBase {
public int BaseProperty { get; set; } = 42;
public BaseMock() {
SetupAll(this, this);
}
public static void SetupAll<TBase>([NotNull] Mock<TBase> mock, [NotNull] TBase instance)
where TBase : class, IBase {
mock.SetupGet(o => o.BaseProperty).Returns(instance.BaseProperty);
}
}
class DerivedMock : Mock<IDerived>, IDerived {
public int BaseProperty { get; set; } = 42;
public int DerivedProperty { get; set; } = 73;
public DerivedMock() {
SetupAll(this, this);
}
public static void SetupAll<TDerived>([NotNull] Mock<TDerived> mock, [NotNull] TDerived instance)
where TDerived : class, IDerived {
BaseMock.SetupAll(mock, instance);
mock.SetupGet(o => o.DerivedProperty).Returns(instance.DerivedProperty);
}
}
public class UnitTest1
{
public void Test() {
BaseMock baseMock = new BaseMock();
IBase baseObject = baseMock.Object;
baseMock.BaseProperty = 37;
Assert.AreEqual(37, baseObject.BaseProperty);
baseMock.VerifyGet(o => o.BaseProperty, Times.Never);
// ----------------
DerivedMock derivedMock = new DerivedMock();
IDerived derivedObject = derivedMock.Object;
derivedMock.BaseProperty = 42;
derivedMock.DerivedProperty = 73;
Assert.AreEqual(42, derivedObject.BaseProperty);
Assert.AreEqual(73, derivedObject.DerivedProperty);
}
}
reason why i wrote it this way is that i can dynamicall change property value AND verify that it was readed / written.
CodePudding user response:
You don't inherit from the Mock
class. Instead you use Mock's Object
property to get the mocked object. To reuse setting up IBase
mock, you can do something like this:
private static void SetupBase<T>(Mock<T> mock)
where T : class, IBase
{
// setup base methods and properties
mock.SetupGet(x => x.BaseProperty).Returns(1);
}
private static void SetupDerived(Mock<IDerived> mock)
{
SetupBase(mock);
// setup derived methods and properties
}
[Test]
public void Test()
{
var derivedMock = new Mock<IDerived>();
SetupDerived(derivedMock);
var derived = derivedMock.Object;
Assert.AreEqual(1, derived.BaseProperty);
derivedMock.SetupGet(x => x.BaseProperty).Returns(2);
Assert.AreEqual(2, derived.BaseProperty);
}