J'ai un test unitaire où je dois me moquer d'une méthode non virtuelle qui renvoie un type booléen
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);
}
}
J'ai donc un objet de XmlCupboardAccess
classe fictif et j'essaie de configurer une simulation pour cette méthode dans mon cas de test, comme indiqué ci-dessous
[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
}
Mais cette ligne jette une exception
Invalid setup on a non-virtual (overridable in VB) member:
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2,
It.IsAny<String>())
Une suggestion pour contourner cette exception?
c#
unit-testing
moq
Rahul Lodha
la source
la source
XmlCupboardAccess
?virtual
. Moq ne peut pas se moquer d'un type concret qu'il ne peut pas remplacer.Réponses:
Moq ne peut pas se moquer des méthodes non virtuelles et des classes scellées. Lors de l'exécution d'un test à l'aide d'un objet fictif, MOQ crée en fait un type de proxy en mémoire qui hérite de votre "XmlCupboardAccess" et remplace les comportements que vous avez définis dans la méthode "SetUp". Et comme vous le savez en C #, vous ne pouvez remplacer quelque chose que s'il est marqué comme virtuel, ce qui n'est pas le cas avec Java. Java suppose que chaque méthode non statique est virtuelle par défaut.
Une autre chose que je pense que vous devriez considérer est l'introduction d'une interface pour votre "CupboardAccess" et commencez à vous moquer de l'interface à la place. Cela vous aiderait à découpler votre code et à avoir des avantages à long terme.
Enfin, il existe des frameworks tels que: TypeMock et JustMock qui fonctionnent directement avec l'IL et peuvent donc se moquer de méthodes non virtuelles. Cependant, les deux sont des produits commerciaux.
la source
Pour aider quiconque a eu le même problème que moi, j'ai accidentellement mal saisi le type d'implémentation au lieu de l'interface, par exemple
au lieu de
la source
Veuillez consulter Pourquoi la propriété que je souhaite simuler doit-elle être virtuelle?
Vous devrez peut-être écrire une interface wrapper ou marquer la propriété comme virtuelle / abstraite car Moq crée une classe proxy qu'il utilise pour intercepter les appels et renvoyer vos valeurs personnalisées que vous avez placées dans l'
.Returns(x)
appel.la source
Au lieu de vous moquer de la classe concrète, vous devriez vous moquer de cette interface de classe. Extraire l'interface de la classe XmlCupboardAccess
Et au lieu de
changer en
la source
Vous obtiendrez également cette erreur si vous vérifiez qu'une méthode d'extension d'une interface est appelée.
Par exemple si vous vous moquez:
Vous obtiendrez la même exception car il
.ValidateAndThrow()
s'agit d'une extension sur l'IValidator<T>
interface.public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...
la source
Code:
mais voyez l'exception.
la source