У меня есть эти интерфейсы:
public interface IBase
{
int Value { get; }
}
public interface IDerived : IBase
{
new int Value { get; set; }
}
Следующий тест работает корректно:
var mock = new Mock<IDerived>( MockBehavior.Strict );
mock.SetupGet( m => m.Value ).Returns( 0 );
IDerived o = mock.Object;
Assert.That( o.Value, Is.EqualTo( 0 ) );
Однако, когда я меняю тип o
на IBase
, я получаю следующую ошибку:
Message: Moq.MockException : IBase.Value invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
Это по дизайну? Нужно ли снимать флаг Strict
, чтобы получить доступ к свойству базового интерфейса (которое скрыто производным интерфейсом)? Или есть какие-то другие настройки, которые я мог бы использовать?
В качестве примечания: был проблема, относящийся к базовым/производным свойствам только для чтения/чтения-записи, но объявленный тип фиктивного объекта там не рассматривался. Может ли это быть другой проблемой в Moq?
Свойство Value
интерфейса IBase
и интерфейса IDerived
не совпадают. Например, вы можете сделать это:
public interface IBase
{
string Value { get; }
}
public interface IDerived : IBase
{
new string Value { get; }
}
public class Implementation : IDerived
{
string IBase.Value { get; } = "Base";
string IDerived.Value { get; } = "Derived";
}
Чтобы правильно смоделировать интерфейс IDerived
, вы должны установить возвращаемое значение для обоих свойств. Метод Mock.As
полезен здесь для приведения интерфейса IDerived
к IBase
.
Mock<IDerived> mock = new Mock<IDerived>( MockBehavior.Strict );
mock.Setup( obj => obj.Value ).Returns( "Derived" );
mock.As<IBase>().Setup( obj => obj.Value ).Returns( "Base" );