I was very happy with Moq until I needed to test a method that takes a delegate as parameter and got an UnsupportedException. The issue is also mentioned here and on Moq issue list .
Is there any framework that supports this kind of mocking?
For example:
///
/// Interfaces
///
public interface IChannelFactory<T> {
TReturn UseService<TReturn>(Func<T, TReturn> function);
}
public interface IService {
int Calculate(int i);
}
///
/// Test
///
Mock<IChannelFactory<IService>> mock = new Mock<IChannelFactory<IService>>();
// This line results in UnsupportedException
mock.Setup(x => x.UseService(service => service.Calculate(It.IsAny<int>()))).Returns(10);
I'm not quite sure what you're trying to do, but this compiles and runs using your interfaces with Moq 4:
var mock = new Mock<IChannelFactory<IService>>();
mock.Setup(x => x.UseService(It.IsAny<Func<IService, int>>())).Returns(10);
int result = mock.Object.UseService(x => 0);
Console.WriteLine(result); // prints 10
See also this answer for a more complex case.
I ran into this same issue recently, and here's how to use moq (v4.0.10827) to test the correct method and parameters are called. (Hint: you need two layers of mocks.)
//setup test input
int testInput = 1;
int someOutput = 10;
//Setup the service to expect a specific call with specific input
//output is irrelevant, because we won't be comparing it to anything
Mock<IService> mockService = new Mock<IService>(MockBehavior.Strict);
mockService.Setup(x => x.Calculate(testInput)).Returns(someOutput).Verifiable();
//Setup the factory to pass requests through to our mocked IService
//This uses a lambda expression in the return statement to call whatever delegate you provide on the IService mock
Mock<IChannelFactory<IService>> mockFactory = new Mock<IChannelFactory<IService>>(MockBehavior.Strict);
mockFactory.Setup(x => x.UseService(It.IsAny<Func<IService, int>>())).Returns((Func<IService, int> serviceCall) => serviceCall(mockService.Object)).Verifiable();
//Instantiate the object you're testing, and pass in the IChannelFactory
//then call whatever method that's being covered by the test
//
//var target = new object(mockFactory.Object);
//target.targetMethod(testInput);
//verifying the mocks is all that's needed for this unit test
//unless the value returned by the IService method is used for something
mockFactory.Verify();
mockService.Verify();
Have a look at Moles. It supports delegates as mocks.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.