Utilizzo di Verifica per confermare i valori dei parametri previsti nella classe MOQ Mock

StackOverflow https://stackoverflow.com/questions/8883685

  •  29-10-2019
  •  | 
  •  

Domanda

Sto cercando di verificare che un metodo all'interno di una finta sia chiamato con un parametro oggetto previsto. Sto usando MOQ, NUNIT e pensando che la somiglianza di AutoFixture dovrebbe svolgere il lavoro. Di seguito è riportata una versione semplificata di ciò che sto cercando di fare.

C'è un modo per farlo con l'autofixture? C'è un modo migliore per verificarlo Something è chiamato con il parametro appropriato?

Equal equal nel file A classe per confrontare i valori delle proprietà e modificare il Verify linea a:

barMock.Verify(m => m.Something(a));

Passa, tuttavia preferirei non sovrascrivere uguali in ogni classe come una nel mio progetto.

namespace Test
{
    using Moq;
    using NUnit.Framework;
    using Ploeh.SemanticComparison.Fluent;

    public class A
    {
        public int P1 { get; set; }
    }
    public interface IBar
    {
        void Something(A a);
    }

    public class Foo
    {
        public A Data { get; private set; }
        public void DoSomethingWith(IBar bar)
        {
            Data = new A { P1 = 1 };
            bar.Something(Data);
        }
    }

    [TestFixture]
    public class AutoFixtureTest
    {
        [Test]
        public void TestSample()
        {
            var foo = new Foo();
            var barMock = new Mock<IBar>();
            var a = new A { P1 = 1 };
            var expectedA = a.AsSource().OfLikeness<A>();

            foo.DoSomethingWith(barMock.Object);

            expectedA.ShouldEqual(foo.Data);   // passes
            barMock.Verify(m => m.Something(expectedA.Value));  // fails
        }
    }
}
È stato utile?

Soluzione

Nel Verify MOQ per impostazione predefinita Verifica l'uguaglianza di riferimento per gli argomenti, quindi passa solo quando si forniscono le stesse istanze (tranne se si è sovrascritti Equals) nei test e nella tua implementazione.

In te è il expectedA.Value restituisce solo il new A { P1 = 1 } creato nel test che ovviamente non è la stessa istanza creata in DoSomethingWith.

Devi usare Moq's It.Is Costruire per testare correttamente questo senza prevalere Equals (In effetti per questo non hai bisogno di AutoFixture):

barMock.Verify(m => m.Something(It.Is<A>(arg => arg.P1 == a.P1)));

Ma se hai più proprietà come P1, P2, P3 ... AutoFixture può essere utile:

barMock.Verify(m => m.Something(It.Is<A>(arg => expectedA.Equals(a))));

Perché non è necessario scrivere manualmente i controlli di eqairità per tutte le proprietà.

Altri suggerimenti

Se si esegue l'aggiornamento a AutoFixture 2.9.1 (o più recente) è possibile chiamare il metodo CreateProxy a somiglianza che emetterà un proxy dinamico per il tipo di destinazione.

Il proxy dinamico generato sovrascrive uguali usando la somiglianza che semplifica la sintassi (parecchio).

Ecco il metodo di prova originale, modificato per utilizzare il proxy di somiglianza:

[Test]
public void TestSample()
{
    var foo = new Foo();
    var barMock = new Mock<IBar>();
    var expected = new A().AsSource().OfLikeness<A>().CreateProxy();
    expected.P1 = 1;

    foo.DoSomethingWith(barMock.Object);

    Assert.True(expected.Equals(foo.Data));     // passes
    barMock.Verify(m => m.Something(expected)); // passes
}

Si noti che rende anche l'affermazione del test molto più specifica che accettare Qualunque esempio.

Puoi trovare maggiori dettagli su questa nuova funzionalità qui.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top