106 votes

Moq verify avec paramètre objet

J'essaie de vérifier un paramètre qui est une classe. Le code testé est correct. Le bogue se trouve dans le test.

J'ai essayé deux méthodes, qui ont toutes deux échoué.

Voici mes tentatives :

1 :

this.MockImageResizeFilter.Verify(m => m.Filter(this.UploadedFileData, new ImageFilterOptions()
    {
        Width = 256,
        Height = 256,
    }));

Cette opération échoue toujours, même si un objet passé comme deuxième paramètre a des propriétés identiques. Le premier paramètre est vérifié sans problème.

2 :

this.MockImageResizeFilter.Setup(m => m.Filter(It.IsAny<byte[]>(), It.IsAny<ImageFilterOptions>()))
    .Callback<byte[], ImageFilterOptions>((data, options) =>
        {
            Assert.AreEqual(this.UploadedFileData, data, "data");
            Assert.AreEqual(filterOptions.Width, options.Width, "Width");
            Assert.AreEqual(filterOptions.Height, options.Height, "Height");
        }
    );

Cela passe toujours, même quand cela devrait échouer. Les assertions dans le callback échouent, mais l'exception n'est pas transmise au contexte externe, et donc le test passe toujours.

Pouvez-vous m'aider à trouver ce que je fais mal ?

178voto

w0lf Points 11825

La première tentative est plus proche de ce que vous voulez atteindre.

La raison pour laquelle cela échoue est que Moq utilise (probablement) Object.Equals sous le couvercle pour vérifier si le ImageFilterOptions avec lequel la méthode a été appelée est la même instance que celle que vous avez fournie dans l'appel à la méthode Verify .

Il est impossible qu'il s'agisse de la même instance, car en Verify vous créez un new ImageFilterOptions() .

Au lieu d'effectuer la vérification des paramètres de cette manière, vous pourriez utiliser la fonction de Moq It.Is pour fournir une expression qui vérifie que le paramètre est bien celui attendu.

Dans votre cas, vous voulez vérifier que le paramètre est de type ImageFilterOptions et que les deux Width et le Height sont fixés à 256 . L'expression qui vous permet de faire cela est :

It.Is<ImageFilterOptions>(p => p.Width == 256 && p.Height == 256)

Donc, votre appel à Verify pourrait ressembler à ça :

this.MockImageResizeFilter.Verify(m => m.Filter(
            this.UploadedFileData,
            It.Is<ImageFilterOptions>(p => p.Width == 256 && p.Height == 256)));

10voto

MarredCheese Points 2206

Moq's Verify vous indique seulement que la méthode n'a jamais été appelée avec les arguments que vous avez spécifiés, sans expliquer quel argument (ou quelle propriété d'un argument) était erroné. Pour obtenir des détails précis, utilisez un callback pour sauvegarder le ou les arguments dans une variable, puis effectuez une assertion par rapport à cette variable :

ImageFilterOptions passedOptions = null;
this.MockImageResizeFilter.Setup(m => m.Filter(It.IsAny<byte[]>(), It.IsAny<ImageFilterOptions>()))
    .Callback<byte[], ImageFilterOptions>((data, options) =>
    {
        passedOptions = options
    });

// <exercise the mocked object>

this.MockImageResizeFilter.Verify(m => m.Filter(this.UploadedFileData, It.IsAny<ImageFilterOptions>());
Assert.AreEqual(expectedOptions.Width, passedOptions.Width, "Width");
Assert.AreEqual(expectedOptions.Height, passedOptions.Height, "Height");

// (If you wanted, you could also use the callback technique to check that
// `this.UploadedFileData` was passed in for the first parameter.)

Cela vous indique exactement quel argument/propriété était erroné.

Vous avez également la possibilité de ne pas tester chaque propriété individuellement, ce qui est intéressant lorsqu'il s'agit d'objets ayant de nombreuses propriétés :

using FluentAssertions;

// ...

passedOptions.Should().BeEquivalentTo(expectedOptions);

(Notez que Être équivalent à met en évidence les défaillances des propriétés individuelles).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X