Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing values of reference parameter within mocked method (Moq)

How can I setup Moq to change the values of an inner method parameter, when the parameter is created within another method. For example (simplified code below):

public class Response
{ 
    public bool Success { get; set; }
    public string[] Messages {get; set;}
}

public class MyBusinessLogic
{
    public void Apply(Response response);
}


public class MyService
{
    private readonly MyBusinessLogic _businessLogic;

    ....

    public Response Insert()
    {
        var response = new Response();   // Creates the response inside here
        _businessLogic.Apply(response);

        if (response.Success) 
        {
            // Do more stuff
        }
    }
}

Let's say I want to unit test the Insert() method. How can I setup the mock of the Business Logic's Apply() method to receive any Response class and have it populate the returning Response object with Success set to true so that the rest of the code can run.

As an aside, I have changed the return type of the Apply() method to be bool (instead of Void) to have Moq simply return true, similar to below:

mockMyBusinessLogic.Setup(x => x.Apply(It.IsAny<Response>()).Returns(true);

But that feels awkward having a method that does something, and returns something (I prefer having methods just doing one or the other).

Hoping for a way that may look "something" like below (when using void):

mockMyBusinessLogic.Setup(
   x => x.Apply(It.IsAny<Response>()).Callback(() 
           => new Response { Success = true });
like image 879
Stefan Zvonar Avatar asked Dec 06 '15 01:12

Stefan Zvonar


1 Answers

You can access argument passed to mock call with Callback<T>(Action<T>) method:

mockMyBusinessLogic
    .Setup(x => x.Apply(It.IsAny<Response>())
    .Callback<Response>(r => r.Success = true);
like image 157
k.m Avatar answered Sep 30 '22 05:09

k.m