Question

J'ai la signature de la méthode suivante dans mon iterface:

void SetItem(ref AddressItem item);

Je fais une contrainte de paramètre comme ceci:

IAddAddressForm form = Substitute.For<IAddAddressForm>();
AddressItem item = null;
form.SetItem(Arg.Is(item));

Mais qui échoue à cause de l'arbitre. Si je prends l'arbitre est interrompu, il fonctionne très bien. Mais je dois passer par référence ici.

Toutes les idées comment obtenir?

Side Note: Mon but ultime est de lancer une exception dans SetItem si la valeur est passée nulle. Si vous pouvez aider à cela, alors vous obtenez des points supplémentaires!

Était-ce utile?

La solution

NSubstitute ne prend pas en charge directe des paramètres ref correspondant arg, mais en général il travaillera avec eux ok.

Je vais supposer que vous devez utiliser ref comme indiqué dans votre question, mais de toute évidence si vous pouvez éviter ref votre API sera plus simple, comme on le tester (quels que soient les cadres que vous utilisez).

En réponse à votre question immédiate, vous pouvez passer un ref en mettant à jour votre deuxième exemple de code à:

form.SetItem(ref item);

Pour votre remarque, assurez-vous que vous essayez de ne pas pousser trop dans votre comportement de remplacement. Je l'ai constaté que chaque fois que je fais cela, il est nécessaire signe I de simplifier la communication entre la classe que je teste et ses dépendances. (Ou si je vraiment besoin de beaucoup de logique dans un objet faux, je céderai code à un plutôt que générer,. Il peut souvent être plus simple)

Il y a quelques façons d'obtenir cet appel à lancer une exception:

form.When(x => x.SetItem(ref item)).Do(x => { throw new ArgumentNullException(); });

lancera une exception que lorsqu'elle est appelée avec un arbitre nul. Vous pouvez également ajouter de manière sélective ce comportement en fonction de l'argument passé, même si je vous conseille contre ce qu'il est probablement un signe que vous poussez trop dans votre substitut.

form.WhenForAnyArgs(x => x.SetItem(ref item))
    .Do(x => {
        if (x[0] == null)
            throw new ArgumentNullException();
    });

Enfin, si vous voulez simplement vérifier que la classe que vous testez répond correctement lorsque IAddAddressForm renvoie une exception null arg, je ferais probablement ceci:

form
    .WhenForAnyArgs(x => x.SetItem(ref item))
    .Do(x => { throw new ArgumentNullException(); });

De cette façon, vous ne se soucient pas vraiment ce que l'argument est, vous voulez juste vous assurer que le code que vous testez réagisse à ce cas correctement.

Hope this helps.

SIDE NOTE:

Si vous voulez utiliser un arg matcher (comme Arg.Any<AddressItem>()) pour un argument out ou ref vous devrez définir en dehors de l'appel lui-même (cela peut être un peu d'erreurs: vous devez vous assurer que vous définissez les matchers dans le même ordre que ils vont dans l'appel):

        IAddAddressForm form = Substitute.For<IAddAddressForm>();
        AddressItem item = Arg.Is<AddressItem>(y => y.Number == 14);
        form
            .When(x => x.SetItem(ref item))
            .Do(x => { throw new ArgumentNullException(); });
        var address = new AddressItem { Number = 14 };
        form.SetItem(ref address);
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top