2016-06-17 14 views
1

FluentAssertionsを使用してコレクションとオブジェクトグラフの比較アサーションを結合しようとしています。FluentAssertions;コレクションとオブジェクトグラフの比較アサーションを組み合わせる

私は以下のクラスを持っています。

public class Contract 
{ 
    public Guid Id { get; set; } 
    public string Name { get; set; } 
} 

これはコレクションに返されます。

ICollection<Contract> contracts = factory.BuildContracts(); 

私はその後コレクションは、特定Contractのオブジェクトが含まれていることを確認します。これは動作しません

contracts.Should().Contain(new Contract() { Id = id1, Name = "A" }); 

Containは(ShouldBeEquivalentToによって提供される)object.Equalsではなく、オブジェクトグラフの比較を、使用しているので、私はだと信じています。

私はまた、すなわち

contracts.Should().NotContain(new Contract() { Id = id2, Name = "B" }); 

が効果的にアイテムの数が不明を含むコレクションを与え、コレクションが特定のオブジェクトが含まれていないことを主張する必要があり、私はそれを確実にしたいです。それにはいくつかの特定の項目が含まれており、複数の特定の項目が含まれていないことがわかります。

が、これはFluentAssertionsが提供する機能を使用して達成することができますか?

側の注意点として、私はここで説明する理由のためobject.Equalsを上書きする必要はありません。 Should I be using IEquatable to ease testing of factories?

答えて

2

protected bool Equals(Contract other) 
{ 
    return Id.Equals(other.Id) && string.Equals(Name, other.Name); 
} 

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

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

とあなたが見ることができるように、それがテストに合格しますフレームワークを使用します。このようなシナリオで

私はthe collections documentation for v3.0 and higherで参照として表現述語を使用する傾向があります。

次の例では、コレクションは、特定Contractのオブジェクトが含まれていることを確認し、またコレクションは、特定のオブジェクトが含まれていないことを主張する方法を示しています。

[TestMethod] 
public void FluentAssertions_Should_Validate_Collections() { 
    //Arrange 
    var id1 = Guid.NewGuid(); 
    var id2 = Guid.NewGuid(); 

    var list = new List<Contract>{ 
     new Contract() { Id = id1, Name = "A" }, 
     new Contract() { Id = Guid.NewGuid(), Name = "B"} 
    }; 

    var factoryMock = new Mock<IContractFactory>(); 
    factoryMock.Setup(m => m.BuildContracts()).Returns(list); 
    var factory = factoryMock.Object; 

    //Act 
    var contracts = factory.BuildContracts(); 

    //Assert 
    contracts.Should() 
     .HaveCount(list.Count) 
     .And.Contain(c => c.Id == id1 && c.Name == "A") 
     .And.NotContain(c => c.Id == id2 && c.Name == "B"); 
} 
1

その後、使用されるご契約Equalsをオーバーライドすることができ、あなたのユニットテストは喜んで渡す必要があります。 ランダムなGUIDを使用している場合は問題があるかもしれませんが、あらかじめ定義されたGUIDを使用しているようです。

次試してみる:それは私がドキュメントと私の経験から言うことができる限りobject.Equalsを使用しない enter image description here

+0

+1と提案に感謝します。しかし、これは本当に私が欲しい答えではありません、私はequalsをオーバーライドし、単に標準の 'Assert.IsTrue(contracts.Contains(...))'を使用していました。しかし、これには独自の問題がありました(http://stackoverflow.com/questions/33988487/should-i-be-using-iequatable-to-ease-testing-of-factories)。私はFluentAssertionsを使用してEqualsのオーバーライドを避けることを望んでいます。 –

+1

興味深いリンク...私はあなたが何かを把握すると確信しています。私はそれがどのように進化するのかを見るためにポストを見守ります:)。ところで、あなたは "[shouldly](https://github.com/shouldly/shouldly)"を実行しましたか?私はそのデフォルト動作が何であるか分かりませんが、あなたが望むように動作するかもしれません。 – Noctis

1

代わりに答えNkosi'sに、あなたはまだexpecationを構築することにより、ShouldBeEquivalentToを使用することができます。

+0

'Should()。Contain(c => c.ShouldBeEquivalentTo(contract1))'のような意味ですか? 'ShouldBeEquivalentTo'が返り値を持たないため、そのメソッドを動作させる方法がわかりません。あなたは「expecationを構築する」という意味ではありません。ありがとう –

+0

'Contract'インスタンスを持つコレクションを期待通りに作成し、それを' ShouldBeEquivalentTo'の期待値として渡してください。厳密な注文を気にする人は、 'options => options.WithStrictOrdering' ' –

+0

を使うこともできます。コレクションに他の' Contracts'が含まれているとどうなりますか?私。コレクションには100個のアイテムが含まれています。そのアイテムに2個の特定のアイテムが含まれていることを確認したい、1個の​​特定のアイテムが含まれていないことを確認します。 –

関連する問題