Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq fake one method but use real implementation of another

Given an interface IService that has Method1() and Method2().

I want to test that when Method1() throws an Exception, Method2() is called and returns a given value.

(Method2() is called when Method1() throws).

Therefore I need to test a real Method2() with a fake Method1(), they are methods of the same interface.

Here is my test code:

MBase sut.MethodX() is the only entry point. It uses IService.

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 of Method2() 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 with MBase.

like image 473
Sam Leach Avatar asked Sep 27 '13 15:09

Sam Leach


People also ask

How do you do MOQ method?

You can use Moq to create mock objects that simulate or mimic a real object. Moq can be used to mock both classes and interfaces. However, there are a few limitations you should be aware of. The classes to be mocked can't be static or sealed, and the method being mocked should be marked as virtual.

How do you call a real method on mocked object?

Mockito allows us to partially mock an object. This means that we can create a mock object and still be able to call a real method on it. To call a real method on a mocked object we use Mockito's thenCallRealMethod().

How do you mock another method in the same class which is being tested C#?

You can either mock the external calls that happen within the getTyreSpecification method or you can pull that method out into its own class, wrapped in an interface, and inject the interface into your Selecter class. That would allow you to mock it.

How does MOQ mock work?

Mock objects allow you to mimic the behavior of classes and interfaces, letting the code in the test interact with them as if they were real. This isolates the code you're testing, ensuring that it works on its own and that no other code will make the tests fail.


1 Answers

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).

like image 104
Sunny Milenov Avatar answered Sep 17 '22 04:09

Sunny Milenov