验证集合已通过

时间:2014-05-20 07:28:51

标签: c# moq

我正在尝试验证复杂的集合是否已传递给方法。

我似乎无法想到如何编写lambda来测试。

以下是我要做的简化版本:

var parameters = new List<NotificationParameter>()
{
    new NotificationParameter()
    {
        Key = "photoShootId",
        Value = 1,
    },
};

message.Verify(m => m.Load(It.Is<List<NotificationParameter>>(
        p => // ??? Ensure that 'p' and 'parameters' have
             //     the same elements and values for 'Key' and 'Value'
    )
));

parameters传递给verify时,测试失败了,所以我想针对KeyValue属性进行测试。

上面的

p类型为List<NotificationParameter>

2 个答案:

答案 0 :(得分:2)

您可以使用.All在每个元素上执行表达式,如果all都返回true,则返回true,因此对于您的特定情况,我们可以将条件写为

message.Verify(m => m.Load(It.Is<List<NotificationParameter>>(
   pList => pList.All(p => parameters.Any(pTest => p.Key == pTest.Key &&  p.Value == pTest.Value))
    )
));

其他方法是使用IEqualityComparer&amp; SequenceEqual

例如

class NotificationParameterComparer : IEqualityComparer<NotificationParameter>
{
    public bool Equals(NotificationParameter x, NotificationParameter y)
    {
        if(x==null || y == null)
            return false;
        return x.Key == y.Key && x.Value == y.Value
    }

    public int GetHashCode(NotificationParameter parameter)
    {
        if (Object.ReferenceEquals(parameter, null)) return 0;

        int hashKey = parameter.Key == null ? 0 : parameter.Key.GetHashCode();

        int hashValue = parameter.Value.GetHashCode();

        return hashKey ^ hashValue;
    }
}

然后将其用作

message.Verify(m => m.Load(It.Is<List<NotificationParameter>>(
    pList => pList.SequenceEqual(parameters, new NotificationParameterComparer())
    )
));

答案 1 :(得分:2)

要匹配列表的内容,可以使用 SequenceEquals() IEqualityComparer&lt;&gt;

public class NotificationParameter {
    public NotificationParameter(string key, int value) {
        Key = key;
        Value = value;
    }
    public string Key { get; set; }
    public int Value { get; set; }
}

public interface IService {
    void Load(IEnumerable<NotificationParameter> parameters);
}

public class ClientClass {
    private readonly IService _service;
    public ClientClass(IService service) {
        _service = service;
    }
    public void Run(IEnumerable<NotificationParameter> parameters) {
        _service.Load(parameters);
    }
}


public class NotificationComparer : IEqualityComparer<NotificationParameter> {
    public bool Equals(NotificationParameter x, NotificationParameter y) {
        return Equals(x.Key, y.Key)
            && x.Value.Equals(y.Value);
    }

    public int GetHashCode(NotificationParameter obj) {
        return obj.Value.GetHashCode() ^ obj.Key.GetHashCode();
    }
}

private readonly static NotificationComparer Comparer = new NotificationComparer();


[TestMethod]
public void VerifyLoadCompareValues() {
    var parameters = new List<NotificationParameter> {
        new NotificationParameter("A", 1),
        new NotificationParameter("B", 2),
        new NotificationParameter("C", 3),
    };


    var expected = new List<NotificationParameter> {
        new NotificationParameter("A", 1),
        new NotificationParameter("B", 2),
        new NotificationParameter("C", 3),
    };


    var mockService = new Mock<IService>();
    var client = new ClientClass(mockService.Object);

    client.Run(parameters);

    mockService.Verify(mk => mk.Load(It.Is<IEnumerable<NotificationParameter>>( it=> it.SequenceEqual(expected,Comparer))));

}

如果订单不一样,那么可以使用排序然后比较的辅助方法。

[TestMethod]
public void VerifyLoadCompareDifferentOrder() {
    var parameters = new List<NotificationParameter> {
        new NotificationParameter("A", 1),
        new NotificationParameter("B", 2),
        new NotificationParameter("C", 3),
    };


    var expected = new List<NotificationParameter> {
        new NotificationParameter("B", 2),
        new NotificationParameter("C", 3),
        new NotificationParameter("A", 1),
    };


    var mockService = new Mock<IService>();
    var client = new ClientClass(mockService.Object);

    client.Run(parameters);

    mockService.Verify(mk => mk.Load(It.Is<IEnumerable<NotificationParameter>>(it => AreSame(expected, it))));

}


private static bool AreSame(
    IEnumerable<NotificationParameter> expected,
    IEnumerable<NotificationParameter> actual
) {
    var ret = expected.OrderBy(e => e.Key).SequenceEqual(actual.OrderBy(a => a.Key), Comparer);
    return ret;
}