Reputation: 513
I am trying to mock a delegate, using Moq, but so far everything im doing is in vain. I have made a small example of how the setup is:
1.A proxy class is abstracting a WCF service
public interface IServiceProxy
{
void FooService(ServiceProxy.FooServiceDelegate service);
}
public class ServiceProxy : IServiceProxy
{
private readonly EndpointAddress _fooServiceEndpoint;
public ServiceProxy(IConfiguration configuration)
{
_fooServiceEndpoint = new EndpointAddress(new Uri(configuration.WcfServiceEndpoint));
}
public delegate void FooServiceDelegate(IFooBar proxy);
public void FooService(FooServiceDelegate service)
{
Do<IFooBar>((service.Invoke), _fooServiceEndpoint);
}
private void Do<T>(UseServiceDelegate<T> f, EndpointAddress address)
{
UsingService<T>.Use(f.Invoke, address);
}
}
2.The service definition
/// <summary>
/// This is the interface the WCF service exposes
/// </summary>
public interface IFooBar
{
string Hello(string name);
}
3.And the class that uses the proxy
public class DoFoo
{
private readonly IServiceProxy _serviceProxy;
public DoFoo(IServiceProxy serviceProxy)
{
_serviceProxy = serviceProxy;
}
public string SayHello(string name)
{
var response = string.Empty;
_serviceProxy.FooService(proxy => { response = proxy.Hello(name); });
return response;
}
}
I would like to test that the methods defined on the delegate FooServiceDelegate
with the input IFooBar
is in fact called and also i would like to be able to mock the responce from a methodcall on a IFooBar
via the delegate.
So far my attempts has been in vain, so i hope that there are some moq experts that can help here.
Here is an example of a test, that of course does not work as it is now.
[TestClass()]
public class DoFooTests
{
[TestMethod, TestCategory("Unit")]
public void SayHelloJohn_ShouldUseServiceProxy()
{//SETUP
var serviceMock = new Mock<IFooBar>(MockBehavior.Loose);
var delegateMock = new Mock<ServiceProxy.FooServiceDelegate>(MockBehavior.Strict);
var serviceProxyMock = new Mock<IServiceProxy>(MockBehavior.Strict);
serviceProxyMock.Setup(m => m.FooService(delegateMock.Object));
var name = "John";
var response = $"Hello {name}";
//Im trying something like this (of course this does not work...)
delegateMock.Setup(m => m.Hello(name)).Returns(response);
//EXECUTE
var doFoo = new DoFoo(serviceProxyMock.Object);
var result = doFoo.SayHello(name);
//ASSERT
// Do some assertions here....
}
}
Upvotes: 7
Views: 6515
Reputation: 8725
You have to call the delegate when FooService
is executed:
[TestMethod]
public void SayHelloJohn_ShouldUseServiceProxy()
{
const string EXPECTED_RESULT = "Hello John";
const string NAME = "John";
var fakeServiceProxy = new Mock<IServiceProxy>(MockBehavior.Strict);
var fakeFooBar = new Mock<IFooBar>(MockBehavior.Loose);
fakeFooBar.Setup(bar => bar.Hello(NAME)).Returns(EXPECTED_RESULT);
fakeServiceProxy.Setup(proxy => proxy.FooService(
It.IsAny<ServiceProxy.FooServiceDelegate>()))
.Callback<ServiceProxy.FooServiceDelegate>(arg => arg(fakeFooBar.Object));
var target = new DoFoo(fakeServiceProxy.Object);
var result = target.SayHello(NAME);
Assert.AreEqual(EXPECTED_RESULT, result);
}
The above snippet execute proxy => { response = proxy.Hello(name); })
when you call SayHello
method.
Upvotes: 5