It looks like the changing of out parameters is not supported out of the box. The best solution I found so far is based on hack - see https://stackoverflow.com/a/19598345/463041. It invokes private method using reflection.
Using that hack, the working solution would look like this:
void Main()
{
var m = new Mock<IFoo>();
string s = "1";
var pg = 0;
m.Setup(p => p.Query(out s))
.OutCallback((out string v) => v = pg==0 ? "1" : "2")
.Returns(() => pg==0)
.Callback(() => { pg++; s = "2"; });
IFoo f = m.Object;
string z;
while (f.Query(out z))
{
z.Dump();
}
z.Dump();
}
public interface IFoo {
bool Query(out string result);
}
public static class MoqExtensions
{
public delegate void OutAction<TOut>(out TOut outVal);
public delegate void OutAction<in T1,TOut>(T1 arg1, out TOut outVal);
public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, TOut>(this ICallback<TMock, TReturn> mock, OutAction<TOut> action)
where TMock : class
{
return OutCallbackInternal(mock, action);
}
public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, T1, TOut>(this ICallback<TMock, TReturn> mock, OutAction<T1, TOut> action)
where TMock : class
{
return OutCallbackInternal(mock, action);
}
private static IReturnsThrows<TMock, TReturn> OutCallbackInternal<TMock, TReturn>(ICallback<TMock, TReturn> mock, object action)
where TMock : class
{
mock.GetType()
.Assembly.GetType("Moq.MethodCall")
.InvokeMember("SetCallbackWithArguments", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Instance, null, mock,
new[] { action });
return mock as IReturnsThrows<TMock, TReturn>;
}
}