使用Params数组的设置方法

时间:2011-11-01 14:33:02

标签: c# nunit moq

我正在为应用程序开发测试。有一个方法有一个params数组作为参数。我已经使用Moq设置了方法但是当我运行测试时,方法的返回值为null,这意味着它没有被模拟。

以下是代码示例:

public interface ITicketManager {
    string GetFirstTicketInQueueIfMatches(params string[] ticketsToMatch);
}

public class TicketManager : ITicketManager {
    private Queue<string> ticketQueue = new Queue<string>();

    public string GetFirstTicketInQueueIfMatches(params string[] ticketsToMatch) {
        var firstQueuedTicket = ticketQueue.Peek();
        var firstQueuedTicketMatchesAnyOfRequested = ticketsToMatch.Any(t => t == firstQueuedTicket);

        if(firstQueuedTicketMatchesAnyOfRequested)
            return firstQueuedTicket;

        return null;
    }
}

模拟代码如下所示:

var mock = new Mock<ITicketManager>();

mock.Setup(m => m.GetFirstTicketInQueueIfMatches(It.IsAny<string>()))
    .Returns(p => { 
    if(p.Contains("A"))
            return "A";

    return null;
});

为什么它永远不会受到模拟方法的影响?

3 个答案:

答案 0 :(得分:67)

您正在尝试使用单个字符串而不是数组来调用方法。请记住,它是处理params部分的C#编译器,将调用代码转换为仅传入数组的调用中的单个值。就方法本身而言,它只是得到一个数组 - 这就是你在嘲笑的。

编译器实际将代码转换为:

mock.Setup(m => m.GetFirstTicketInQueueIfMatches
                        (new string[] { It.IsAny<string>() }))

这不是你想要的。

您应该使用:

mock.Setup(m => m.GetFirstTicketInQueueIfMatches(It.IsAny<string[]>()))

如果您需要验证它只被赋予一个值,那么您需要以与非params参数相同的方式执行此操作。

基本上,params只会对C#编译器产生影响 - 而不是moq

答案 1 :(得分:12)

我认为params string必须与It.IsAny<string[]>()匹配,而不是It.IsAny<string>()

答案 2 :(得分:0)

使用Moq,以下代码可在带有params参数的方法上设置回调。将第二个参数定义为数组可以解决问题。

        MockLogger
            .Setup(x => x.Info(It.IsAny<string>(), It.IsAny<object[]>()))
            .Callback<string, object[]>((x, y) => _length = x.Length);