7

xUnit を使用していますが、カスタム タイプの場合に 2IEnumerable<T>が等しいかどうかを判断する方法がありません。T

を使用してみましLINQ SequenceEqualたが、インスタンスTが異なるため、これは false を返します。

これは、機能しない基本的なテストですIEqualityComparer

    [Fact]
    public void FactMethodName()
    {
        var one = new[] { new KeywordSchedule() { Id = 1 } };
        var two = new[] { new KeywordSchedule() { Id = 1 } };

        Assert.Equal(one, two, new KeywordScheduleComparer());
    }

public class KeywordScheduleComparer : IEqualityComparer<IEnumerable<KeywordSchedule>>
{
    public bool Equals(IEnumerable<KeywordSchedule> x, IEnumerable<KeywordSchedule> y)
    {
        return Object.ReferenceEquals(x, y) || (x != null && y != null && x.SequenceEqual(y));
    }

    public int GetHashCode(IEnumerable<KeywordSchedule> obj)
    {
        if (obj == null)
            return 0;

        return unchecked(obj.Select(e => e.GetHashCode()).Aggregate(0, (a, b) => a + b));  // BAD
    }
}

これを統合テストで使用しているので、最初に IEnumerable から DB にデータを挿入し、SUT を呼び出して DB からデータを取得して比較します。

コレクションの比較を機能させるのを手伝っていただければ幸いです。

4

3 に答える 3

16

これが xUnit.net 1.9.2 で正常に動作することを確認しました:

public class MyClass
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class MyClassComparer : IEqualityComparer<MyClass>
{
    public bool Equals(MyClass x, MyClass y)
    {
        return x.ID == y.ID;
    }

    public int GetHashCode(MyClass obj)
    {
        return obj.ID.GetHashCode();
    }
}

public class ExampleTest
{
    [Fact]
    public void TestForEquality()
    {
        var obj1 = new MyClass { ID = 42, Name = "Brad" };
        var obj2 = new MyClass { ID = 42, Name = "Joe" };

        Assert.Equal(new[] { obj1 }, new[] { obj2 }, new MyClassComparer());
    }
}

したがって、追加の比較子が必要な理由は 100% わかりません。単一の比較子だけで十分です。

于 2013-09-10T16:16:13.750 に答える
0

FluentAssertionsライブラリを使用して、これをよりエレガントに行うことができます。コレクション用のアサーション メソッドが多数あります。

public class MyClass
{
    public int ID { get; set; }
    public string Name { get; set; }

    protected bool Equals(MyClass other)
    {
        return ID == other.ID;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != GetType()) return false;
        return Equals((MyClass) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (ID*397) ^ (Name != null ? Name.GetHashCode() : 0);
        }
    }
}

public class ExampleTest
{
    [Fact]
    public void TestForEquality()
    {
        var obj1 = new MyClass { ID = 42, Name = "Rock" };
        var obj2 = new MyClass { ID = 42, Name = "Paper" };
        var obj3 = new MyClass { ID = 42, Name = "Scissors" };
        var obj4 = new MyClass { ID = 42, Name = "Lizard" };

        var list1 = new List<MyClass> {obj1, obj2};
        list1.Should().BeEquivalentTo(obj3, obj4);
    }
}
于 2013-09-11T15:09:11.297 に答える