Я пытаюсь проверить, сложная коллекция была передана в метод.
Кажется, я не могу представить, как написать лямбду для проверки.
Вот упрощенная версия того, что я пытаюсь сделать:
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>
.
Вы можете использовать. .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 & 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())
)
));
Для соответствия содержимому списка можно использовать SequenceEquals() и IEqualityComparer <>
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;
}
.All