web-dev-qa-db-fra.com

Méthode d'installation avec tableau de paramètres

Je développe des tests pour une application. Il existe une méthode qui a un tableau params comme paramètre. J'ai configuré la méthode à l'aide de Moq mais lorsque j'exécute le test, la valeur de retour de la méthode est nulle, ce qui signifie qu'elle n'est pas ridiculisée.

Voici un exemple de code:

public interface ITicketManager {
    string GetFirstTicketInQueueIfMatches(params string[] ticketsToMatch);
}

public class TicketManager : ITicketManager {
    private Queue<string> ticketQueue = new Queue<string>();

    public string GetFirstTicketInQueueIfMatches(params string[] ticketsToMatch) {
        var firstQueuedTicket = ticketQueue.Peek();
        var firstQueuedTicketMatchesAnyOfRequested = ticketsToMatch.Any(t => t == firstQueuedTicket);

        if(firstQueuedTicketMatchesAnyOfRequested)
            return firstQueuedTicket;

        return null;
    }
}

Le faux code ressemble à ceci:

var mock = new Mock<ITicketManager>();

mock.Setup(m => m.GetFirstTicketInQueueIfMatches(It.IsAny<string>()))
    .Returns(p => { 
    if(p.Contains("A"))
            return "A";

    return null;
});

Pourquoi ne frappe-t-il jamais la méthode moquée?

49
Luis Aguilar

Vous essayez d'appeler une méthode prenant une seule chaîne, plutôt qu'un tableau. Gardez à l'esprit que c'est le compilateur C # qui gère la partie params, convertissant le code appelant qui spécifie simplement les valeurs individuelles en un appel passant dans un tableau. En ce qui concerne la méthode elle-même, il s'agit simplement d'obtenir un tableau - et c'est ce que vous vous moquez.

Le compilateur est en fait transformer votre code en:

mock.Setup(m => m.GetFirstTicketInQueueIfMatches
                        (new string[] { It.IsAny<string>() }))

ce n'est pas ce que vous voulez.

Tu devrais utiliser:

mock.Setup(m => m.GetFirstTicketInQueueIfMatches(It.IsAny<string[]>()))

Si vous devez vérifier qu'il ne reçoit qu'une seule valeur, vous devrez le faire de la même manière que pour un paramètre non paramétrique.

Fondamentalement, params fait seulement une différence pour le compilateur C # - pas pour moq.

74
Jon Skeet

Je pense que le params string Doit correspondre à It.IsAny<string[]>() plutôt qu'à It.IsAny<string>()

12
Wiktor Zychla

À l'aide de Moq, le code ci-dessous fonctionne pour configurer un rappel sur une méthode avec un argument params. Définir le deuxième argument comme un tableau fait l'affaire.

        MockLogger
            .Setup(x => x.Info(It.IsAny<string>(), It.IsAny<object[]>()))
            .Callback<string, object[]>((x, y) => _length = x.Length);
0
Ben Wesson