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

Moq подделывает один метод, но использует реальную реализацию другого

Для интерфейса IService, который имеет Method1() и Method2().

Я хочу проверить, что когда Method1() выдает Exception, Method2(), а возвращает заданное значение.

(Method2() вызывается, когда Method1() бросает).

Поэтому мне нужно протестировать реальный Method2() с подделкой Method1(), это методы одного и того же интерфейса.

Вот мой тестовый код:

MBase sut.MethodX() - единственная точка входа. Он использует IService.

Моя цель - утверждать, что Method2() возвращает что-то.

// Arrange
// Fake bytes in.
var networkStreamMock = new Mock<INetworkStream>();
networkStreamMock.Method1(x => x.Read(It.IsAny<byte[]>(), It.IsAny<int>(), It.IsAny<int>())).Returns(It.IsAny<byte[]>());

// Force throw TimeoutException.
var mock = new Mock<IService>();
mock.Setup(x => x.Method1(new Message
{ 
    Xml = Xml,  
}
)).Throws<TimeoutException>();

// Check Method 2 is called. (this is done in its own test so commented out)
// mock.Setup(m => m.Method2(It.IsAny<Message>())).Verifiable();

// New MBase.
IKernel kernel = new StandardKernel(new FakeBindings());
kernel.Rebind<IService>().ToConstant(mock.Object);
MBase sut = kernel.Get<M>();

// Act
sut.MethodX(networkStreamMock.Object);

// Here I would like to assert on the return value of Method2
mock.Verify(m => m.Method2(It.IsAny<Message>()));

Возможно ли это с помощью Moq или другой издевательской структуры? Как мне это сделать? Я могу создать ручной макет с поддельной реализацией Method1() и реальной реализацией Method2(), но мне интересно, есть ли лучший подход.

Я уже тестировал IService по отдельности, но теперь я хочу протестировать его взаимодействие с MBase.

4b9b3361

Ответ 1

Вы можете сделать это с помощью

var mock = new Mock<MyNetworkStream>(){ CallBase = true };
mock.Setup(m => m.Method1....

В приведенном выше коде будет использоваться реальная реализация MyNetworkStream для любого метода/свойства, которое явно не настроено. То есть он будет вызывать реальный Method2(), а Method1() будет измененной версией.

CallBase=true обычно предназначен для тестирования абстрактных классов (если это правильно или неправильно, выходит за рамки этого вопроса).

Ответ 2

В этом случае (если там еще не будет больше), я просто создаю свой собственный тестовый класс, расширяющий класс с реальным поведением, который реализует интерфейс, который вам нужно высмеять. Таким образом, вы можете высмеять одно значение и вернуться к базовому классу для реальной функциональности.