Moq:使用方法调用序列发送的测试参数

Ton*_*gan 1 c# moq

我是C#Moq(过去使用过Rhino Mochs)的新手,需要测试一系列对同一方法的调用.我发现这个很酷的解决方案可以测试一系列返回值:

http://haacked.com/archive/2009/09/29/moq-sequences.aspx/

public static class MoqExtensions
{
  public static void ReturnsInOrder<T, TResult>(this ISetup<T, TResult> setup, 
    params TResult[] results) where T : class  {
    setup.Returns(new Queue<TResult>(results).Dequeue);
  }
}
Run Code Online (Sandbox Code Playgroud)

我需要做的是在对同一方法的一系列调用中测试作为参数发送(而不是它返回的值).

粗略轮廓......

 var expression = new MyExpressionThing();

 processor.Setup(x => x.Execute(expected1)).Verifiable();
 processor.Setup(x => x.Execute(expected2)).Verifiable();
 processor.Setup(x => x.Execute(expected3)).Verifiable();

 expression.ExecuteWith(processor.Object);
 processor.Verify();
Run Code Online (Sandbox Code Playgroud)

这是我尝试过但我得到的例外情况:

"System.ArgumentException:无效的回调.带参数的方法(String,Object [])上的设置无法使用参数(String)调用回调."

 // Arrange
 var processor = new Mock<IMigrationProcessor>();
 IList<string> calls = new List<string>();
 processor.Setup(p => p.Execute(It.IsAny<string>()))
    .Callback<string>(s => calls.Add(s));

// Act
var expr = new ExecuteScriptsInDirectoryExpression { SqlScriptDirectory = @"SQL2\1_Pre" };
expr.ExecuteWith(processor.Object);

// Assert
calls.ToArray().ShouldBe(new[]
   { "DELETE FROM PRE1A", "DELETE FROM PRE1B", "INSERT INTO PRE2\r\nLINE2" });
Run Code Online (Sandbox Code Playgroud)

看起来我正在使用Moq"入门"示例中的样板代码:

此链接讨论此异常以及指向触发它的Moq代码的链接.

http://dailydevscoveries.blogspot.com.au/2011/04/invalid-callback-setup-on-method-with.html

Joe*_*ite 6

我会在每次调用mock时使用回调来捕获参数,然后断言结果:

var parameters = new List<ParameterType>();
processor.Setup(x => x.Execute(It.IsAny<ParameterType>()))
    .Callback<ParameterType>(param => parameters.Add(param));

CallCodeUnderTest(processor.Object);

Assert.That(parameters, Is.EqualTo(new[] { expected1, expected2, expected3 }));
Run Code Online (Sandbox Code Playgroud)

更新:根据您引用的错误消息,看起来您正在模拟的方法采用的是第二个参数params object[].调用方法时不需要指定该参数(这就是Setuplambda中不需要它的原因),但是你需要在泛型类型参数中指定它.Callback.将您的Callback行更改为:

    .Callback<string, object[]>((s, o) => calls.Add(s));
Run Code Online (Sandbox Code Playgroud)