ThBlitz
ThBlitz

Reputation: 513

Moq. Mock delegate input

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

Answers (1)

Old Fox
Old Fox

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

Related Questions