Метод установки макета объекта с аргументами для динамического возврата

#.net #unit-testing #mocking #moq

#.net #модульное тестирование #издевательство #moq

Вопрос:

У меня есть позиция класса, и я хочу протестировать метод CreatePosition. Метод выглядит следующим образом:

 public Position CreatePosition(int horizontalIndex, int verticalIndex)
{
    return new Position(horizontalIndex, verticalIndex);
}
 

IPosition интерфейса:

 public interface IPosition
{
     char HorizontalPosition { get; }
     int VerticalPosition { get; }
     int IndexHorizontal { get; }
     int IndexVertical { get; }
     Position CreatePosition(int horizontalIndex, int verticalIndex);
}
 

Здесь используется метод CreatePosition, и он динамический — для каждой пары параметров он создает новую позицию:

     private void AddToAllowedPositions(IPosition positionCreator)
    {
          int horizontalIndex = piece.Position.IndexHorizontal;
          int verticalIndex = piece.Position.IndexVertical;

          while(IndexesAreValid(horizontalIndex, verticalIndex)
         {
                IPosition currentPosition = positionCreator.CreatePosition(horizontalIndex, verticalIndex);
                allowedPosition.Add(currentPosition);
         }
    }
 

Моя проблема в том, что я не знаю, как подделать метод CreatePosition.

Я создал Mock<IPosition> вот так:

 Mock<IPosition> positionCreator = new Mock<IPosition>();
positionCreator.Setup(positionCreator.Object.CreatePosition(?, ?)).Returns( ?? );
 

Я хотел бы подделать этот метод, чтобы он принимал динамические параметры и возвращал динамические результаты, точно так же, как это делает real Position. Возможно ли это сделать?

Ответ №1:

Возможно, что-то подобное в вашем методе тестирования:

 positionCreator
    .Setup(x => x.CreatePosition(It.IsAny<int>, It.IsAny<int>))
    .Returns(new Position(givenHorizontalIndex, givenVerticalIndex));
 

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

Или вы хотите что-то более сложное, где вы бы подключили все это в [SetUp] метод, например, учитывая этот ввод, вернуть этот вывод?

Комментарии:

1. Спасибо за ответ. Есть ли способ вернуть макет объекта вместо новой позиции? Что-то вроде Mock<IPosition> ?

2. нет, метод Returns описывает, что фактический метод ( CreatePosition ) вернет при вызове во время теста, поэтому он должен получать параметр того же типа, что и возвращаемый тип метода

3. Существует также проблема, потому что это. IsAny<int> — это универсальный метод, который возвращает int , это не целое число.

4. это просто способ сказать, что, если метод вызывается с любым int параметром, он вернет то, что вы настроили для возврата; альтернативой может быть что-то вроде .Setup(x => x.CreatePosition(2, 3) , что означает, что только если метод будет вызван с этими конкретными параметрами во время теста, он вернет настройку (в противном случае это будет невозможно).вернет значение null — если вы не выполните другую настройку, то есть)

5. Как насчет giveHorizontalIndex, givenVerticalIndex? Они не определены, но они должны быть динамическими.