Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Moq callback with out parameter

I'm trying to use Moq to mock a callback for the following method signature:

ResponseHeader AddIncentives(
        Hs_transRow[] data,
        out ResponseBody responseBody);

I want my callback to use the data which is passed in. However, I'm running into problems which I think are because the second parameter is an out parameter. I can setup and return data without problems, but the callback is an issue.

This is my current setup:

var addIncentiveResponseBody = new ResponseBody();

mockCoinsService
.Setup(service => service.AddIncentives(It.IsAny<Hs_transRow[]>(), out addIncentiveResponseBody))
.Callback((Hs_transRow[] data, ResponseBody body) =>
{
    //I want to use the data variable here
})
.Returns(() => new ResponseHeader
{
     action = ResponseHeaderAction.RESPONSE,
});

When I run this code as part of a unit test, I get the error:

Invalid callback. Setup on method with parameters (Hs_transRow[],ResponseBody&) cannot invoke callback with parameters (Hs_transRow[],ResponseBody).

I can see there is an ampersand difference, which I assume is because that parameter should be an out parameter. However, if I add the out keyword to the callback (and assign it a value within the callback), I get the build time error:

Delegate 'Action' does not take two arguments.

Is Moq unable to handle a callback for a method which has an out parameter, or am I doing something wrong?

[Edit] To clarify beyond any doubt, I am not asking how to set the value of the out parameter. This is already being done by the line:

var addIncentiveResponseBody = new ResponseBody();
like image 997
Tim Avatar asked Mar 16 '16 13:03

Tim


1 Answers

This was pointed out in the comments by Jeroen Heier but adding it as an answer should make it more visible. Scott Wegner has written an OutCallback overload which can be used.

This is used as follows:

mockCoinsService
    .Setup(service => service.AddIncentives(It.IsAny<Hs_transRow[]>(), out addIncentiveResponseBody))
    .OutCallback((Hs_transRow[] data, ResponseBody body) =>
    {
        //I can now use the data variable here
    })
    .Returns(() => new ResponseHeader
    {
         action = ResponseHeaderAction.RESPONSE,
    });
like image 123
Tim Avatar answered Oct 28 '22 03:10

Tim