J'ai une interface préexistante ...
public interface ISomeInterface
{
void SomeMethod();
}
et j'ai étendu cette interface en utilisant un mixin ...
public static class SomeInterfaceExtensions
{
public static void AnotherMethod(this ISomeInterface someInterface)
{
// Implementation here
}
}
J'ai une classe qui appelle ça que je veux tester ...
public class Caller
{
private readonly ISomeInterface someInterface;
public Caller(ISomeInterface someInterface)
{
this.someInterface = someInterface;
}
public void Main()
{
someInterface.AnotherMethod();
}
}
et un test où j'aimerais me moquer de l'interface et vérifier l'appel à la méthode d'extension ...
[Test]
public void Main_BasicCall_CallsAnotherMethod()
{
// Arrange
var someInterfaceMock = new Mock<ISomeInterface>();
someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();
var caller = new Caller(someInterfaceMock.Object);
// Act
caller.Main();
// Assert
someInterfaceMock.Verify();
}
L'exécution de ce test génère cependant une exception ...
System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()
Ma question est, y a-t-il une bonne façon de se moquer de l'appel mixin?
c#
unit-testing
mocking
extension-methods
moq
Russell Giddings
la source
la source
Réponses:
Vous ne pouvez pas simuler "directement" une méthode statique (d'où la méthode d'extension) avec un framework moqueur. Vous pouvez essayer Moles ( http://research.microsoft.com/en-us/projects/pex/downloads.aspx ), un outil gratuit de Microsoft qui met en œuvre une approche différente. Voici la description de l'outil:
Vous pouvez utiliser Moles avec n'importe quel framework de test (c'est indépendant à ce sujet).
la source
J'ai utilisé un wrapper pour contourner ce problème. Créez un objet wrapper et transmettez votre méthode simulée.
Voir Mocking Static Methods for Unit Testing par Paul Irwin, il a de beaux exemples.
la source
J'ai trouvé que je devais découvrir l'intérieur de la méthode d'extension pour laquelle j'essayais de me moquer de l'entrée et de me moquer de ce qui se passait à l'intérieur de l'extension.
J'ai considéré l'utilisation d'une extension comme l'ajout de code directement à votre méthode. Cela signifiait que je devais me moquer de ce qui se passe à l'intérieur de l'extension plutôt que de l'extension elle-même.
la source
Vous pouvez simuler une interface de test qui hérite de la vraie et a un membre avec la même signature que la méthode d'extension.
Vous pouvez ensuite simuler l'interface de test, ajouter la vraie à la maquette et appeler la méthode de test dans la configuration.
Votre implémentation du simulacre peut alors appeler la méthode de votre choix ou simplement vérifier que la méthode est appelée:
Merci à la solution Håvard S dans cet article pour savoir comment implémenter une maquette prenant en charge deux interfaces. Une fois que je l'ai trouvé, l'adapter avec l'interface de test et la méthode statique était un jeu d'enfant.
la source
SomeNotAnExtensionMethod
etSomeNotAnExtensionMethod
? J'ai maintenant une idée de comment créer une signature de méthode d'extension dans une interface ...iReal
paramètreSomeExtensionMethod
en cas deITest
? Si vous le transmettez comme premier paramètre, comment procédez-vous à l'installation?Setup( x=> x.SomeExtensionMethod(x, ...)
cela provoquera une exception d'exécution.object _mockCache = whatever
... `Setup (x => x.SomeExtensionMethod (...) .. Callback (() => you can accéder à _mockCache ici);)Vous pouvez facilement simuler une méthode d'extension avec JustMock . L'API est la même que la méthode normale moqueuse. Considérer ce qui suit
Pour organiser et vérifier cette méthode, utilisez ce qui suit:
Voici également un lien vers la documentation: Mocking des méthodes d'extension
la source
J'aime utiliser le wrapper (modèle d'adaptateur) lorsque j'emballe l'objet lui-même. Je ne suis pas sûr que j'utiliserais cela pour envelopper une méthode d'extension, qui ne fait pas partie de l'objet.
J'utilise une propriété interne Lazy Injectable de type Action, Func, Predicate ou Delegate et permet d'injecter (échanger) la méthode lors d'un test unitaire.
Ensuite, vous appelez Func au lieu de la méthode réelle.
Pour un exemple plus complet, consultez http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/
la source
Donc, si vous utilisez Moq et que vous souhaitez moquer le résultat d'une méthode d'extension, vous pouvez l'utiliser
SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn())
sur l'instance de la classe fictive qui a la méthode d'extension que vous essayez de simuler.Ce n'est pas parfait, mais à des fins de test unitaire, cela fonctionne bien.
la source