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

时间:2014-02-24 03:50:46

标签: 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);
  }
}

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

粗略轮廓......

 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();

这是我尝试过的,但我得到了例外:

“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" });

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

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

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

1 个答案:

答案 0 :(得分: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 }));

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

Callback