Подтвердить что ты не робот

Moq - вызов метода Verify, который имеет значение params

Я пытаюсь проверить с помощью Moq, что метод, который имеет список "params", вызывается, но по какой-то причине это не работает. Подпись метода выглядит примерно так:

void AttachAsModifiedToOrders(IOrder order, params 
       Expression<Func<IOrder, object>>[] modifiedProperties);

Затем в настройке Mock я сделал что-то вроде этого, чтобы сделать простой "remove/insert" из изделенной коллекции:

MockEntities.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<DataAccess.Order>()))
    .Callback<IOrder, Expression<Func<IOrder, object>>[]>((order, expr) => 
      { Orders.Remove(Orders.Where(o => o.Id== order.Id).First()); 
      Orders.Add((DataAccess.Order)order); });

Наконец, проверка:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), 
     It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1));

Я проверил, и код выполняет ok, и метод вызывается (издевается над ним), но проверка не выполняется. я что-то упускаю? или это просто, что этот вызов "params" не поддерживается Moq?

4b9b3361

Ответ 1

Мне было трудно воспроизвести это. Я думаю, что в вашей проверке есть опечатка:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object>>>()), Times.Exactly(1));

Должно быть:

MockEntities.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<Order>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Exactly(1));

Мне также интересно, должен ли первый It.IsAny быть интерфейсом, а не конкретным типом?

Однако это слишком сложный тест некоторой функциональности, а в образце кода отсутствуют некоторые фрагменты, например, тип DataAccess или экземпляр класса (не уверен?), порядок и заказы.

Чтобы обойти это, я создал интерфейс IOrder и объект манипулятора, который использует интерфейс, его немного бессмысленно, но он запускает тест:

public interface IOrder
{
    void AttachAsModifiedToOrders(IOrder order, params Expression<Func<IOrder, object[]>>[] modifiedProperties);

}

public class Manipulator
{
    public Manipulator(IOrder order)
    {
        Expression<Func<IOrder, object[]>> exp = o => new object[0];
        order.AttachAsModifiedToOrders(order, exp);
    }

    public void DoStuff() { }
}

Затем я создал тестовое устройство для проверки параметров arg:

[TestFixture]
public class Tester
{
    [Test]
    public void Test()
    {
        var order = new Mock<IOrder>();
        order.Setup(n => n.AttachAsModifiedToOrders(It.IsAny<IOrder>()));

        var manipulator = new Manipulator(order.Object);
        manipulator.DoStuff();

        order.Verify(x => x.AttachAsModifiedToOrders(It.IsAny<IOrder>(), It.IsAny<Expression<Func<IOrder, object[]>>>()), Times.Once());
    }
}

Это работает для меня, поэтому я не думаю, что проблема - это значение params и Moq напрямую. Я действительно думаю, что вам будет хорошо, чтобы сделать шаг назад и посмотреть, действительно ли вы тестируете класс, взаимодействующий с Mock, или пытаетесь проверить интегрированные способы использования нескольких разных типов. Параметрами и деревом выражений также является запах.