MOQ支持输出参数的设置 - 没问题。我希望能够通过Returns()或Callback()根据调用中传递的内容设置参数。我的用例涉及使用out参数模拟一个方法。
以下是我用于实验的内容,到目前为止每次都有负面结果:
public interface ITestClass
{
string method(string inString, out string outString);
}
public class TestClass : ITestClass
{
public string method(string inString, out string outString)
{
outString = inString + " was passed in";
return (inString + " was returned");
}
}
[TestFixture]
public class OutTest
{
[Test]
public void Test()
{
//Arrange
Mock<ITestClass> mock = new Mock<ITestClass>(MockBehavior.Strict);
string stringParm = "value that will be assigned to out parameter";
mock.Setup(t => t.method(It.IsAny<string>(), out stringParm))
.Returns((string i, string o) =>
{
return i + " was returned"; // o = stringParm already
})
.Callback((string s, string oo) =>
{
stringParm = s + " was passed in"; // oo = stringParm already
});
TestClass real = new TestClass();
string testString = DateTime.Now.ToLongTimeString();
//Act
string realOut;
string mockOut;
string realResult = real.method(testString, out realOut);
string mockResult = mock.Object.method(testString, out mockOut);
//Assert
realResult.Should().Be(mockResult); // passes
realOut.Should().Be(mockOut); // fails - mockout = original stringParm
}
}
答案 0 :(得分:0)
我知道这不理想,但为什么不传递预期的mockOut
代替"value that will be assigned to out parameter"
?
带
string stringParm = "foo was passed in"
答案 1 :(得分:0)
我最近不得不更新我使用的解决方案,以便在没有参数的情况下对设置执行回调。
namespace SupRep.TestUtilities
{
using System.Reflection;
using Moq.Language;
using Moq.Language.Flow;
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 delegate void OutAction<in T1,in T2,TOut>(T1 arg1, T2 arg2, 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);
}
public static IReturnsThrows<TMock, TReturn> OutCallback<TMock, TReturn, T1, T2, TOut>(this ICallback<TMock, TReturn> mock, OutAction<T1, T2, 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
{
var methodCall = mock.GetType().GetProperty("Setup").GetValue(mock);
mock.GetType().Assembly.GetType("Moq.MethodCall")
.InvokeMember("SetCallbackResponse", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, methodCall,
new[] { action });
return mock as IReturnsThrows<TMock, TReturn>;
}
}}