NSubstitute ne prend pas directement en charge les paramètres de correspondance d'arg, mais en général, il fonctionne avec eux.
Je vais supposer que vous devez utiliser ref
comme indiqué dans votre question, mais évidemment si vous pouvez éviter ref
votre API sera plus simple, tout comme le tester (indépendamment des 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 note côté, assurez-vous que vous essayez de ne pas trop pousser le comportement dans votre substitut . J'ai constaté que chaque fois que je fais cela, c'est un signe dont j'ai besoin pour simplifier la communication entre la classe que je suis en train de tester et ses dépendances. (Ou si j'ai vraiment besoin de beaucoup de logique dans un faux objet, je vais en programmer un plutôt que de le générer, cela peut souvent être plus simple.)
Il existe plusieurs façons d'obtenir cet appel pour lancer une exception :
form.When(x => x.SetItem(ref item)).Do(x => { throw new ArgumentNullException(); });
Ceci déclenchera une exception uniquement s'il est appelé avec une référence nulle. Vous pouvez également ajouter ce comportement de manière sélective en fonction de l'argument adopté, bien que je vous déconseille car c'est probablement un signe que vous insistez trop sur votre remplaçant.
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 lance une exception arg nulle, je ferais probablement ceci:
form
.WhenForAnyArgs(x => x.SetItem(ref item))
.Do(x => { throw new ArgumentNullException(); });
De cette façon, vous n Peu importe ce que l'argument est, vous voulez juste vous assurer que le code que vous testez réagit correctement à ce cas.
Espérons que cela aide.
SIDE NOTE:
Si vous souhaitez utiliser un matcher arg (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 devrez vous assurer que vous définissez les coupleurs dans le même ordre que 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);
Je suis vraiment curieux de savoir pourquoi vous devez utiliser 'ref' ici. Pouvez-vous s'il vous plaît expliquer? –
Eh bien, je fais un exemple de projet pour former mon département informatique sur les tests unitaires utilisant NSubstitute et Moles. Dans le cadre de ce que je veux mole Linq-To-SQL. Pour ce faire, j'ai dû effectuer une mise à jour vers un objet renvoyé par une requête Linq-to-sql. J'ai trouvé que si je ne passais pas l'objet avec le 'ref' alors la mise à jour a échoué (Parce qu'il ne recongnized plus l'objet comme celui demandé.) Cela peut ne pas être la" meilleure pratique "pour linq à sql, mais je suis test de l'unité de formation, pas Linq. – Vaccano
Vous pouvez voir la question/réponse qui a conduit à mon code étant comme ça ici: http://stackoverflow.com/questions/3766417/save-changes-in-linq-to-sql/3770482#3770482 – Vaccano