我正在尝试验证复杂的集合是否已传递给方法。
我似乎无法想到如何编写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
时,测试失败了,所以我想针对Key
和Value
属性进行测试。
p
类型为List<NotificationParameter>
。
答案 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;
}