it-swarm.com.de

C # - Das Feststellen von zwei Objekten ist in Komponententests gleich

Entweder mit Nunit oder Microsoft.VisualStudio.TestTools.UnitTesting. Im Moment versagt meine Behauptung.

    [TestMethod]
    public void GivenEmptyBoardExpectEmptyBoard()
    {
        var test = new Board();

        var input = new Board()
            {
                Rows = new List<Row>()
                    {
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                    }
            };

        var expected = new Board()
        {
            Rows = new List<Row>()
                    {
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                        new Row(){Cells = new List<int>(){0,0,0,0}},
                    }
        };

        var lifeOrchestration = new LifeOrchestration();

        var actual = lifeOrchestration.Evolve(input);

        Assert.AreEqual(expected, actual);
    }
14

Sie haben zwei verschiedene Board-Instanzen, daher schlägt der Aufruf von Assert.AreEqual fehl. Selbst wenn der gesamte Inhalt identisch zu sein scheint, vergleichen Sie Referenzen und nicht die zugrunde liegenden Werte.

Sie müssen angeben, was zwei Board-Instanzen gleich macht.

Sie können es in Ihrem Test tun:

Assert.AreEqual(expected.Rows.Count, actual.Rows.Count);
Assert.AreEqual(expected.Rows[0].Cells[0], actual.Rows[0].Cells[0]);

// Lots more tests of equality...

Oder Sie können es in Ihren Klassen tun: (Ich habe dies direkt geschrieben - Sie möchten dies anpassen)

public class Board
{
    public List<Row> Rows = new List<Row>();

    public override bool Equals(object obj)
    {
        var board = obj as Board;

        if (board == null)
            return false;

        if (board.Rows.Count != Rows.Count)
            return false;

        return !board.Rows.Where((t, i) => !t.Equals(Rows[i])).Any();
    }

    public override int GetHashCode()
    {
        // determine what's appropriate to return here - a unique board id may be appropriate if available
    }
}

public class Row
{
    public List<int> Cells = new List<int>(); 

    public override bool Equals(object obj)
    {
        var row = obj as Row;

        if (row == null)
            return false;

        if (row.Cells.Count != Cells.Count)
            return false;

        if (row.Cells.Except(Cells).Any())
            return false;

        return true;
    }

    public override int GetHashCode()
    {
        // determine what's appropriate to return here - a unique row id may be appropriate if available
    }
}
15
Grant

Früher habe ich getHasCode und equals überschrieben, aber ich habe es nie gemocht, da ich meinen Produktionscode nicht ändern möchte, um Unit-Tests durchzuführen.

Dann habe ich zu sehr nachgedacht, um Objekte zu vergleichen, die weniger invasiv waren ... aber das ist ziemlich viel Arbeit (viele Eckfälle).

Am Ende verwende ich:

http://www.nuget.org/packages/DeepEqual/

Funktioniert super.

9
foobarcode

ExpectedObjects würde Ihnen helfen, Gleichheit nach Eigenschaftswert zu vergleichen. Es unterstützt:

  1. einfaches Objekt: expected.ToExpectedObject (). ShouldEqual (actual);
  2. collection: expected.ToExpectedObject (). ShouldEqual (actual);
  3. zusammengesetztes Objekt: expected.ToExpectedObject (). ShouldEqual (actual);
  4. partieller Vergleich: erwartetes Objekt muss mit anonymem Typ erstellt werden und erwartet erwartet.ToExpectedObject (). ShouldMatch (actual)

Ich liebe ExpectedObjects, weil ich nur die 2-API aufrufen muss, um den Vergleich der Objektgleichheit zu bestätigen:

  1. ShouldEqual ()
  2. ShouldMatch () für den teilweisen Vergleich
7
In91

Ich wollte eine Lösung, die keine Abhängigkeit hinzufügte, arbeitete mit VS-Komponententests, verglich die Feldwerte von zwei Objekten und erzählte mir alle ungleichen Felder. Das ist was ich mir ausgedacht habe. Beachten Sie, dass er auch erweitert werden kann, um mit Eigenschaftswerten zu arbeiten.

In meinem Fall funktioniert dies gut für den Vergleich der Ergebnisse einiger Dateiparsing-Logik, um sicherzustellen, dass zwei technisch "verschiedene" Einträge Felder mit denselben Werten haben.

    public class AssertHelper
    {
        public static void HasEqualFieldValues<T>(T expected, T actual)
        {
            var failures = new List<string>();
            var fields = typeof(T).GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
            foreach(var field in fields)
            {
                var v1 = field.GetValue(expected);
                var v2 = field.GetValue(actual);
                if (v1 == null && v2 == null) continue;
                if(!v1.Equals(v2)) failures.Add(string.Format("{0}: Expected:<{1}> Actual:<{2}>", field.Name, v1, v2));
            }
            if (failures.Any())
                Assert.Fail("AssertHelper.HasEqualFieldValues failed. " + Environment.NewLine+ string.Join(Environment.NewLine, failures));
        }
    }

    [TestClass]
    public class AssertHelperTests
    {
        [TestMethod]     
        [ExpectedException(typeof(AssertFailedException))]           
        public void ShouldFailForDifferentClasses()
        {            
            var actual = new NewPaymentEntry() { acct = "1" };
            var expected = new NewPaymentEntry() { acct = "2" };
            AssertHelper.HasEqualFieldValues(expected, actual);
        }
    }
6
Daniel

Assert-Methoden verlassen sich auf Equals und GetHashcode des Objekts. Sie können dies implementieren, aber wenn diese Objektgleichheit außerhalb von Komponententests nicht erforderlich ist, würde ich stattdessen einen Vergleich der einzelnen primitiven Typen des Objekts in Betracht ziehen. Es sieht so aus, als wären die Objekte einfach genug und das Überschreiben von Gleichgestellten ist nicht wirklich gerechtfertigt.

0
TGH

Für triviale Objekte wie Domänenobjekte oder DTOs oder Entitäten können Sie einfach beide Instanzen zu einer Zeichenfolge serialisieren und diese Zeichenfolge vergleichen:

var object1Json = JsonConvert.SerializeObject(object1);
var object2Json = JsonConvert.SerializeObject(object2);

Assert.AreEqual(object1Json, object2Json);

Dies hat natürlich verschiedene Vorbehalte. Bewerten Sie daher, ob der JSON-Code für Ihre Klassen die erwarteten Werte enthält, die verglichen werden sollten.

Wenn Ihre Klasse beispielsweise nicht verwaltete Ressourcen oder anderweitig nicht serialisierbare Eigenschaften enthält, werden diese nicht ordnungsgemäß verglichen. Standardmäßig werden auch nur öffentliche Eigenschaften serialisiert.

0
CodeCaster