Проверка прошла успешно

1

Я пытаюсь проверить, сложная коллекция была передана в метод.

Кажется, я не могу представить, как написать лямбду для проверки.

Вот упрощенная версия того, что я пытаюсь сделать:

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>.

Теги:
moq

2 ответа

2
Лучший ответ

Вы можете использовать. .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())
    )
));
  • 1
    Благодарю. Я проголосовал за тебя как за ответ, потому что ты добавил метод, используя .All
2

Для соответствия содержимому списка можно использовать 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;
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню