I have a interface and class that looks like this:
public interface IServiceFacade
{
TResult Execute<TResult>(Func<IService, TResult> operation);
}
public class ServiceFacade : IServiceFacade
{
private readonly string endpoint = "EndPoint";
public TResult Execute<TResult>(Func<IService, TResult> operation)
{
// Call to remote WCF service that results in a TResult
return TResult;
}
}
The IService
interface represent a WCF service running remotely, thus no implementationinstance of this interface is available in the class.
And i call this method twice like this:
public class ServiceConsumer
{
public ServiceConsumer(IServiceFacade serviceFacade)
{
var returnInteger1 = serviceFacade.Execute(service => service.Method1("StringArgument1"));
var returnInteger2 = serviceFacade.Execute(service => service.Method1("StringArgument2"));
}
}
In my unit test I want to stub the returnvalue of the first call to be 1 and the second call to be 2.
Example testmethod
[Test]
public void TestMethod()
{
var serviceFacadeStub = MockRepository.GenerateStub<IServiceFacade>();
serviceFacadeStub.Stub(call => call.Execute(Arg<Func<IService, int>.Matches(?))).Return(1);
serviceFacadeStub.Stub(call => call.Execute(Arg<Func<IService, int>.Matches(?))).Return(2);
var sut = new ServiceConsumer(serviceFacadeStub);
}
I can't figure out what to put in Matches
, or maybe im better off using something other than matches.
Right now im using RhinoMocks and NUnit but if theres a better framework to do this im open to suggestions.
In most cases mocking methods with Func
/Action
is a little bit tricky(In any mock framework I know...)
Usually you have to execute the given Func
/Action
and then the result should affect the rest of the unit under test.
The following snippet shows the easist way to solve your problem:
[Test]
public void TestMethod(
{
var fakeService = MockRepository.GenerateStub<IService>();
fakeService.Stub(x => x.Method1("StringArgument1")).Return(1);
fakeService.Stub(x => x.Method1("StringArgument2")).Return(2);
var serviceFacadeStub = MockRepository.GenerateStub<IServiceFacade>();
serviceFacadeStub.Stub(call => call.Execute(Arg<Func<IService, int>>.Is.Anything))
.WhenCalled(invocation =>
{
var func = (Func<IService, int>)invocation.Arguments[0];
invocation.ReturnValue = func(fakeService);
}).Return(0);
var shouldBeOne = serviceFacadeStub.Execute(service => service.Method1("StringArgument1"));
var shouldBeTwo = serviceFacadeStub.Execute(service => service.Method1("StringArgument2"));
Assert.AreEqual(1, shouldBeOne);
Assert.AreEqual(2, shouldBeTwo);
}
I execute the lambda with fakeService
then return the result based on the given argument.
Another option is to use Matches
as you did, but then you'll have to use reflection to analyze the lambda...(It is much more complicated....)