Moq - проверка вызова метода со значением params - PullRequest
12 голосов
/ 09 марта 2011

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

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

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

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));

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

1 Ответ

12 голосов
/ 09 марта 2011

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

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 или экземпляр класса (не уверены?), Order и Orders.

Чтобы обойти это, я создал интерфейс 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, или пытаетесь проверить интегрированное использование пары различных типов. Дерево параметров и выражений тоже немного пахнет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...