Eu tenho um teste de unidade em que eu tenho que zombar de um método não virtual que retorna um tipo de 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);
}
}
Portanto, eu tenho um objeto de XmlCupboardAccess
classe falso e estou tentando configurar o mock para esse método no meu caso de teste, como mostrado abaixo
[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
}
Mas esta linha lança exceção
Invalid setup on a non-virtual (overridable in VB) member:
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2,
It.IsAny<String>())
Alguma sugestão de como contornar essa exceção?
c#
unit-testing
moq
Rahul Lodha
fonte
fonte
XmlCupboardAccess
?virtual
. O Moq não pode simular um tipo concreto que não pode substituir.Respostas:
O Moq não pode simular métodos não virtuais e classes seladas. Durante a execução de um teste usando objeto simulado, o MOQ na verdade cria um tipo de proxy na memória que herda do seu "XmlCupboardAccess" e substitui os comportamentos que você configurou no método "SetUp". E como você sabe em C #, você pode substituir algo apenas se estiver marcado como virtual, o que não é o caso do Java. Java pressupõe que todo método não estático seja virtual por padrão.
Outra coisa que acredito que você deve considerar é a introdução de uma interface para o seu "CupboardAccess" e, em vez disso, comece a zombar da interface. Isso o ajudaria a desacoplar seu código e obter benefícios a longo prazo.
Por fim, existem estruturas como: TypeMock e JustMock, que funcionam diretamente com a IL e, portanto, podem simular métodos não virtuais. Ambos, no entanto, são produtos comerciais.
fonte
Como ajuda a qualquer pessoa que tenha o mesmo problema que eu, acidentalmente digitei incorretamente o tipo de implementação em vez da interface, por exemplo
ao invés de
fonte
Consulte Por que a propriedade que eu quero zombar precisa ser virtual?
Pode ser necessário escrever uma interface do wrapper ou marcar a propriedade como virtual / abstrata, pois o Moq cria uma classe de proxy usada para interceptar chamadas e retornar seus valores personalizados que você coloca na
.Returns(x)
chamada.fonte
Em vez de zombar da classe concreta, você deve zombar dessa interface de classe. Extrair interface da classe XmlCupboardAccess
E em vez de
mudar para
fonte
Você também receberá esse erro se estiver verificando se um método de extensão de uma interface é chamado.
Por exemplo, se você estiver zombando:
Você receberá a mesma exceção, porque
.ValidateAndThrow()
é uma extensão naIValidator<T>
interface.public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...
fonte
Código:
mas veja a exceção.
fonte