У меня есть модульный тест, где я должен смоделировать не виртуальный метод, который возвращает тип bool
public class XmlCupboardAccess
{
public bool IsDataEntityInXmlCupboard(string dataId,
out string nameInCupboard,
out string refTypeInCupboard,
string nameTemplate = null)
{
return IsDataEntityInXmlCupboard(_theDb, dataId, out nameInCupboard, out refTypeInCupboard, nameTemplate);
}
}
Итак, у меня есть фиктивный объект XmlCupboardAccess
класса, и я пытаюсь настроить макет для этого метода в моем тестовом примере, как показано ниже
[TestMethod]
Public void Test()
{
private string temp1;
private string temp2;
private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
_xmlCupboardAccess.Setup(x => x.IsDataEntityInXmlCupboard(It.IsAny<string>(), out temp1, out temp2, It.IsAny<string>())).Returns(false);
//exception is thrown by this line of code
}
Но эта строка выдает исключение
Invalid setup on a non-virtual (overridable in VB) member:
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2,
It.IsAny<String>())
Любое предложение, как обойти это исключение?
c#
unit-testing
moq
Рахул Лодха
источник
источник
XmlCupboardAccess
?virtual
. Мок не может издеваться над конкретным типом, который он не может переопределить.Ответы:
Moq не может высмеивать не виртуальные методы и запечатанные классы. Во время выполнения теста с использованием фиктивного объекта MOQ фактически создает прокси-тип в памяти, который наследуется от вашего «XmlCupboardAccess» и переопределяет поведение, настроенное вами в методе «SetUp». И, как вы знаете в C #, вы можете переопределить что-то, только если оно помечено как виртуальное, что не так с Java. Java предполагает, что каждый нестатический метод является виртуальным по умолчанию.
Еще одна вещь, на которую, я полагаю, вам стоит обратить внимание, это ввести интерфейс для вашего «CupboardAccess» и вместо этого начать дразнить интерфейс. Это поможет вам отделить ваш код и получит преимущества в долгосрочной перспективе.
Наконец, существуют такие платформы, как: TypeMock и JustMock, которые работают напрямую с IL и, следовательно, могут имитировать не виртуальные методы. Оба, однако, являются коммерческими продуктами.
источник
В качестве помощи любому, у кого была такая же проблема, как у меня, я случайно набрал тип реализации вместо интерфейса, например
вместо того
источник
Посмотри пожалуйста почему собственность, которую я хочу высмеять, должна быть виртуальной?
Возможно, вам придется написать интерфейс-оболочку или пометить свойство как виртуальное / абстрактное, поскольку Moq создает прокси-класс, который он использует для перехвата вызовов и возврата ваших пользовательских значений, которые вы указали в
.Returns(x)
вызове.источник
Вместо того, чтобы издеваться над конкретным классом, вы должны высмеивать интерфейс этого класса. Извлечь интерфейс из класса XmlCupboardAccess
И вместо
изменить на
источник
Вы также получите эту ошибку, если убедитесь, что вызывается метод расширения интерфейса.
Например, если вы издеваетесь:
Вы получите то же исключение, потому что
.ValidateAndThrow()
это расширениеIValidator<T>
интерфейса.public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...
источник
Код:
но вижу исключение.
источник