Domanda

Sto creando il test dell'unità che dovrà confrontare due oggetti dello stesso tipo membro. Ho deciso di utilizzare la Biblioteca SemanticComparison per gestire questa attività senza scrivere il codice comparatore personalizzato. Funziona molto bene quando si confrontano gli oggetti piatti, ci sono problemi quando l'oggetto contiene un oggetto nidificato che deve essere confrontato anche in modo stretto.

public class Outer
{
    public string Name { get; set; }
    public Inner Inner { get; set; }
}

public class Inner
{
    public string Name { get; set; }
    public string Value { get; set; }
}

public class Service
{
    public Outer Method()
    {
        return new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value1"
            }
        };
    }
}
.

Questo non funzionerà perché l'oggetto interiore è confrontato per riferimento, non in memberwise:

    [Test]
    public void SimpleTest1()
    {

        // setup
        var expectedLikeness = new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value1"
            }
        }.AsSource().OfLikeness<Outer>();

        var sut = new Service();
        // exercise sut
        var actual = sut.Method();
        // verify
        expectedLikeness.ShouldEqual(actual);
    }
.

Per farlo funzionare ho dovuto creare proxy dell'oggetto nidificato in modo che sovrascrive l'implementazione ugualmente predefinita.

    [Test]
    public void SimpleTest2()
    {

        // setup
        var expectedLikeness = new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value1"
            }.AsSource().OfLikeness<Inner>().CreateProxy()
        }.AsSource().OfLikeness<Outer>();

        var sut = new Service();
        // exercise sut
        var actual = sut.Method();
        // verify
        expectedLikeness.ShouldEqual(actual);
    }
.

Bene, funziona correttamente, ma immagina che dopo qualche rifacimento del codice di servizio introduciamo il bug che causa la proprietà del valore della classe interna essere diversa dal valore atteso. La caratteristica bella del semanticomparison è che può registrare il nome del membro che causa la disuguaglianza. Ma, in questo caso, tornerà solo "interiore" come mancata corrispondenza, non il nome della proprietà specifica nella classe interna.

Sono percorsi qualcosa? È possibile configurarlo per essere in grado di restituire il membro di Mismatch.

Questo è ovviamente un problema per semplici strutture dati come in questo esempio, ma potrebbe essere un inconveniente per testare un codice di vita reale.

È stato utile?

Soluzione

Dal momento che nessuno ha risposto, fornirò la mia risposta.

Quindi, sembra che non puoi farlo Ootb, a meno che non scrivi un codice extra. Ho avvolto il codice in set di metodi di estensione. Questi metodi consentono di specificare quali proprietà interne / proprietà di raccolta devono essere confrontate utilizzando la somiglianza interiore, non per riferimento. Non è necessario creare manualmente alcun proxy, tutto è gestito internamente da queste estensioni. E i risultati di tutti i confronti interni sono registrati, in modo da poter vedere esattamente quale membro non ha valore non valido.

Ecco il test dalla domanda con l'utilizzo del metodo di estensione "All'internikeness".

    [Test]
    public void ServiceTest3()
    {
        // setup
        var expected = new Outer()
        {
            Name = "outerName",
            Inner = new Inner()
            {
                Name = "innerName",
                Value = "value2"
            }
        };

        var expectedLikeness = expected.AsSource().OfLikeness<Outer>()
            .WithInnerLikeness(d => d.Inner, s => s.Inner)
            ;

        var sut = new Service();
        // exercise sut
        var actual = sut.Method();
        // verify
        expectedLikeness.ShouldEqual(actual);
    }
.

È possibile visualizzare le proprietà del valore degli oggetti interni non corrispondono, quindi il test deve fallire. E non riesce con i seguenti messaggi nell'output:

Comparing inner properties using likeness. Source: s => s.Inner Destination: d => d.Inner.
The source and destination values are not equal. Details: The provided value ClassLibrary1.Inner did not match the expected value ClassLibrary1.Inner. The following members did not match:
- Value.

Ploeh.SemanticComparison.LikenessException : The provided value ClassLibrary1.Outer did not match the expected value ClassLibrary1.Outer. The following members did not match:
- Inner.
.

Puoi trovare il codice sorgente e altri esempi su GitHub.

https://github.com/jmansar/semanticcomparisonexsensons

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