10

私は構造体を持っています例:

public struct Foo
{
    public int Bar;
    public string Baz;
}

オートフィクスチャを使用してユニットテストで作成したいと思います。私は以下を使ってみました:

IFixture fixture = new Fixture();
var f = fixture.CreateAnonymous<Foo>();

しかし、これはAutoFixture was unable to create an instanceエラーをスローします。autofixtureを使用して構造体を自動作成することは可能ですか?これはどのように行うことができますか?私はレガシーコードに取り組んでいるため、構造体を処理する必要があることに注意してください。:)

編集 :

かわった

IFixture fixture = new Fixture().Customize(new AutoMoqCustomization());

IFixture fixture = new Fixture();

質問には関係がなかったので。

4

2 に答える 2

11

これは基本的に、C# コンパイラが値の型を処理する方法の成果物です。ドキュメントは別の方法を示しているようですが、リフレクションの観点から見ると、Foo 構造体にはパブリック コンストラクターがありません。

たとえば、次のコードを実行すると:

var ctors = typeof(Foo).GetConstructors();

結果は空の配列です。

ただし、このコードは次のようにコンパイルされます。

var f = new Foo();

そのため、AutoFixture は Foo のインスタンスを作成できるはずだと主張できます。

ただし、最終的には、変更可能な構造体は悪であり、何としてでも避ける必要があります。より良いオプションは、Foo の実装を次のように変更することです。

public struct Foo
{
    public Foo(int bar, string baz)
    {
        this.Bar = bar;
        this.Baz = baz;
    }

    public readonly int Bar;
    public readonly string Baz;
}

これを行うと、(より) 正しい値の型が得られるだけでなく、AutoFixture はそれ以上変更せずにインスタンスを作成することもできます。

したがって、これはテストに耳を傾けるべきGOOSパラダイムのかなり良い例です。摩擦がある場合、それは製品コードに関するフィードバックである可能性があります。この場合、これはまさに、値型の実装に欠陥があるために自分自身を撃とうとしているというフィードバックです。

PS上記のようにFoo構造体を「修正」したとしても、それをクラスではなく構造体にする意味は何ですか? これにはまだ文字列 (参照型) フィールドが含まれているため、構造体自体はスタック上に存在しますが、文字列フィールドは依然としてヒープ内のデータを指しています。


この問題を AutoFixture の新機能として追加しました。

于 2012-10-18T04:11:22.267 に答える
1

このブログ投稿からヒントを得て、私はを実装するクラスを作成しましたISpecimenBuilder

class FooBuilder : ISpecimenBuilder
{
  public object Create(object request, ISpecimenContext context)
  {
    var sr = request as SeededRequest;
    if (sr == null)
    {
        return new NoSpecimen(request);
    }
    if (sr.Request != typeof(Foo))
    {
        return new NoSpecimen(request);
    }

    var foo = new Foo();
    foo.Bar = context.CreateAnonymous<int>();
    foo.Baz = context.CreateAnonymous<string>();
    return foo;
  }
}

そして、カスタマイズとしてクラスを追加しました

fixture.Customizations.Add(new FooBuilder());

呼び出しをCreateAnonymous<Foo>機能させます。

すぐに使える解決策が他にもある場合は、投稿してください。回答として受け入れます。

于 2012-10-17T14:31:40.090 に答える