Moq fake one method but use real implementation of another
Solution 1
You can do this with:
var mock = new Mock<MyNetworkStream>(){ CallBase = true };
mock.Setup(m => m.Method1....
The above code will use the real implementation of MyNetworkStream for any method/property which is not explicitly setup. I.e. it'll call the real Method2(), while the Method1() will be the mocked version.
CallBase=true
is usually meant to test abstract classes (if this is right or wrong, is out of the scope of this question).
Solution 2
In this case (unless there's a lot more going on) I would just create my own test class extending the class with the real behavior, that implements the interface you need to mock. This way you can mock the one value, and fallback to the base class for the real functionality.
Related videos on Youtube
Comments
-
Sam Leach over 3 years
Given an interface
IService
that hasMethod1()
andMethod2()
.I want to test that when
Method1()
throws anException
,Method2(
) is called and returns a given value.(
Method2()
is called whenMethod1()
throws).Therefore I need to test a real
Method2()
with a fakeMethod1()
, they are methods of the same interface.Here is my test code:
MBase sut.MethodX()
is the only entry point. It usesIService
.My aim is to assert that
Method2()
returns something.// Arrange // Fake bytes in. var networkStreamMock = new Mock<INetworkStream>(); networkStreamMock.Method1(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>())).Returns(It.IsAny<byte[]>()); // Force throw TimeoutException. var mock = new Mock<IService>(); mock.Setup(x => x.Method1(new Message { Xml = Xml, } )).Throws<TimeoutException>(); // Check Method 2 is called. (this is done in its own test so commented out) // mock.Setup(m => m.Method2(It.IsAny<Message>())).Verifiable(); // New MBase. IKernel kernel = new StandardKernel(new FakeBindings()); kernel.Rebind<IService>().ToConstant(mock.Object); MBase sut = kernel.Get<M>(); // Act sut.MethodX(networkStreamMock.Object); // Here I would like to assert on the return value of Method2 mock.Verify(m => m.Method2(It.IsAny<Message>()));
Is this possible with Moq or another mocking framework? How do I do it? I can create a manual mock with a fake implementation of
Method1()
and a real implementation ofMethod2()
but I wonder if there is a better approach.I have already tested
IService
in isolation but I now wish to test it's interaction withMBase
. -
Jeppe Stig Nielsen over 10 yearsIf the class
MyNetworkStream
implementsMethod1
by a public method which does not have thevirtual
(orabstract
oroverride
) modifier, can you still setup thisMethod1
on aMock<MyNetworkStream>
? -
Sam Leach over 10 years@JeppeStigNielsen, no I don't think you can. In my case both my methods are coming from an abstract class.
-
vijay over 4 yearsYou mean ? var mock = new Mock<INetworkStream>(){ CallBase = true };
-
TDao over 2 yearsthis only works if the methods are virtual in the class. I think OP want to mock the interface that the class inherits from, without modifying the class implementation to make the methods virtual.