3

Autofixture のCreateProxy メソッド に関する以前の質問で、潜在的なバグが特定されました。

この失敗したテストはその結果ではないと思いますが、むしろ Likeness.Without(...).CreateProxy() 構文がどのように機能するかについての私の継続的な混乱です。オブジェクトの新しいインスタンスを作成し、その作成がSUTであると見なして、元のテスト を少しだけ複雑にする次の失敗したテストを考えてみましょう。

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange: intent -> use the fixture-created Band as Object Mother
    var template = new Fixture().Create<Band>();

    // act: intent -> instantiated Band *is* the SUT
    var createdBand = new Band {Brass = template.Brass,
                                Strings = template.Brass};

    //   intent -> specify that .Brass should not be considered in comparison 
    var likeness = template.AsSource().OfLikeness<Band>().
        Without(x => x.Brass).CreateProxy(); // Ignore .Brass property

    // per [https://stackoverflow.com/a/15476108/533958] explicity assign
    // properties to likeness
    likeness.Strings = template.Strings;
    likeness.Brass = "foo"; // should be ignored

    // assert: intent -> check equality between created Band & template Band
    //         to include all members not excluded in likeness definition
    likeness.Should().Be(createdBand);          // Fails
    likeness.ShouldBeEquivalentTo(createdBand); // Fails
    Assert.True(likeness.Equals(createdBand));  // Fails
}

ここにバンドがあります:

public class Band
{
    public string Strings { get; set; }
    public string Brass { get; set; }
}

の以前の質問Sourceは、 が一般的にどうあるLikenessべきかを理解するのに役立つほど複雑ではありませんでした。

ソースはSUTの出力である必要がありますか? その場合、AutoFixture によって作成されたテンプレートインスタンスと比較されますか?

または、ソースはAutoFixture によって作成されたテンプレートインスタンスである必要があります。その場合、 SUTの出力と比較されますか?

編集:テストのエラーを修正

プロパティをと新しいインスタンスのtemplate.Brassプロパティの両方に誤って割り当てたことに気付きました。更新されたテストは修正を反映しており、6 つのアサーションすべてがパスするようになりました。Brass StringsBandvar createdBand = new Band {Brass = template.Brass, Strings = template.Strings}

[Fact]
public void Equality_Behaves_As_Expected()
{
    // arrange: intent -> use the fixture-created Band as Object Mother
    var template = new Fixture().Create<Band>();

    // act: intent -> instantiated Band *is* the SUT
    var createdBand = new Band {Brass = template.Brass, Strings = template.Strings};

    // likeness of created
    var createdLikeness = createdBand.AsSource().OfLikeness<Band>().
        Without(x => x.Brass).CreateProxy(); // .Brass should not be considered in comparison 

    // https://stackoverflow.com/a/15476108/533958 (explicity assign properties to likeness)
    createdLikeness.Strings = createdBand.Strings;
    createdLikeness.Brass = "foo"; // should be ignored

    // likeness of template
    var templateLikeness = template.AsSource().OfLikeness<Band>()
        .Without(x => x.Brass)
        .CreateProxy();
    templateLikeness.Strings = template.Strings;
    templateLikeness.Brass = "foo";

    // assert: intent -> compare created Band to template Band
    createdLikeness.Should().Be(template);
    createdLikeness.ShouldBeEquivalentTo(template);
    Assert.True(createdLikeness.Equals(template));

    templateLikeness.Should().Be(createdBand);
    templateLikeness.ShouldBeEquivalentTo(createdBand);
    Assert.True(templateLikeness.Equals(createdBand));
}
4

1 に答える 1

3

つまり、次のとおりです。

likeness.Should().BeAssignableTo<Band>(); // Returns true.

提供されている例では、から生成されたプロキシは からLikeness派生したタイプであり、セマンティック比較アルゴリズムを使用してBandオーバーライドされます。Equals

次のリフレクションを使用します。

createdBand.GetType().IsAssignableFrom(likeness.GetType()) // Returns true.

更新

createBandおよびtemplateインスタンスは、メソッドの影響を受けません。なぜ彼らはすべきですか?CreateProxy

LikenessCreateProxyを使用すると、基本的に次のことができるカスタム等価アサーションを作成できます。

Assert.True(likeness.Equals(createdBand)); // Passed. 

これがないと、元の等価アサーションは失敗します。

Assert.True(template.Equals(createdBand)); // Failed.

ただし、次の場合も失敗します。

Assert.True(likeness.Equals(template));

Strings値がcreatedBandインスタンスのものであるため、失敗します。

Likenessこの動作は予期されたものであり、直接使用して確認できます。

 createdBand.AsSource().OfLikeness<Band>()
     .Without(x => x.Brass).ShouldEqual(template);

出力:

 The provided value `Band` did not match the expected value `Band`. The following members did not match:
      - Strings.
于 2013-03-22T07:21:50.303 に答える