У нас достаточно сложная иерархия интерфейса, и я изо всех сил пытаюсь заставить Moq делать то, что я хочу.
У меня есть интерфейс IReservation
, который расширяет IRulesReservation
и скрывает его перечислитель с новой реализацией другого типа.
public interface IReservation : IRulesReservation
{
new IEnumerator<IRoutePart> GetEnumerator();
}
IRulesReservation
расширяется IEnumerable
.
public interface IRulesReservation : IEnumerable<IRulesRoutePart>
{
}
Метод, который я пытаюсь проверить, использует IReservation
, но в различных точках необходим доступ к IEnumerable<IRulesRoutePart>
. Мой Макет настроен так:
m_mock = new Mock<IReservation>();
m_mock.As<IRulesReservation>().Setup(r => r.GetEnumerator()).Returns(routeParts.Select(rp => (IRulesRoutePart)rp).GetEnumerator());
В этом примере routeParts
представляет собой список IRouteParts
, полученный из Mock<IRouteParts>
объектов, настроенных с помощью .As<IRulesRoutePart>()
.
Всякий раз, когда я сталкиваюсь с небольшим количеством кода в тестируемой функции, использующей перечислитель, он проходит итерацию, как будто коллекция пуста.
Я что-то не так делаю в моей настройке? Или Moq просто не в состоянии обработать счетчик, который скрыт таким образом?
Редактировать: странное поведение, которое я только что заметил при запуске тестового кода на макете:
Assert.That((reservation.Object as IRulesReservation).Count() == 8);
Assert.That((reservation.Object as IEnumerable<IRulesRoutePart>).Count() == 8);
Первая строка пройдет, но вторая строка не пройдёт.
Я попытался изменить макет, чтобы специально настроить перечислитель для IEnumerable<IRulesRoutePart>
, но безрезультатно:
m_mock.As<IEnumerable<IRulesRoutePart>>().Setup(r => r.GetEnumerator()).Returns(routeParts.Select(rp => (IRulesRoutePart)rp).GetEnumerator());