13

ストレージ用にEntity Frameworkを使用したMVC4プロジェクトがあります。私たちのテストでは、最近 Autofixture を使い始めましたが、本当に素晴らしいです。

私たちのモデル グラフは非常に深く、通常、AutoFixture で 1 つのオブジェクトを作成すると、グラフ全体が作成されます: Person -> Team -> Departments -> Company -> Contracts -> ....など。

これの問題は時間です。オブジェクトの作成には最大 1 秒かかります。そして、これは遅いテストにつながります。

私がよくやっているのは、次のようなことです。

        var contract = fixture.Build<PersonContract>()
            .Without(c => c.Person)
            .Without(c => c.PersonContractTemplate)
            .Without(c => c.Occupation)
            .Without(c => c.EmploymentCompany)
            .Create<PersonContract>();

そして、これは機能し、迅速です。しかし、この過度な仕様はテストを読みにくくし、時には.With(c => c.PersonId, 42)unimportant のリストのような重要な詳細を失うことがあり.Without()ます。

これらの無視されたオブジェクトはすべて、Entity Framework のナビゲーション プロパティであり、すべて仮想です。

仮想メンバーを無視するよう AutoFixture に指示するグローバルな方法はありますか?

を作成しようとしましISpecimentBuilderたが、うまくいきません:

public class IgnoreVirtualMembers : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {

        if (request.GetType().IsVirtual // ?? this does not exist )
        {
             return null;
        }
    }
}

ISpecimenBuilder構築しているオブジェクトが別のクラスの仮想メンバーであることを検出する方法が見つからないようです。おそらくISpecimenBuilder、これはこれを行うのに適切な場所ではありません。他のアイデアはありますか?

4

2 に答える 2

23

マークのブログでもう少し読んでください(これは特に)私がやりたいことをする方法を見つけました:

/// <summary>
/// Customisation to ignore the virtual members in the class - helps ignoring the navigational 
/// properties and makes it quicker to generate objects when you don't care about these
/// </summary>
public class IgnoreVirtualMembers : ISpecimenBuilder
{
    public object Create(object request, ISpecimenContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException("context");
        }

        var pi = request as PropertyInfo;
        if (pi == null)
        {
            return new NoSpecimen(request);
        }

        if (pi.GetGetMethod().IsVirtual)
        {
            return null;
        }
        return new NoSpecimen(request);
    }
}

そして、これらをカスタマイズにラップできます。

public class IgnoreVirtualMembersCustomisation : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customizations.Add(new IgnoreVirtualMembers());
    }
}

したがって、テストでは次のようにします。

var fixture = new Fixture().Customize(new IgnoreVirtualMembersCustomisation());

複雑なモデルを作成します。

楽しみ!

于 2013-03-29T16:34:18.560 に答える
3

私はこれと同じ問題を抱えていたので、さらに一歩進んで、ナビゲーション プロパティを遅延読み込みするためのカスタマイズを作成することにしました。プロジェクトはGithubNuGetにあります。

循環依存関係を持つ以下の単純なオブジェクト グラフを考えてみましょう。

class Foo
{
    public int Id { get; set; }
    public int BarId { get; set; }
    public virtual Bar Bar { get; set; }
}

class Bar
{
    public int Id { get; set; }
    public int FooId { get; set; }
    public virtual Foo Foo { get; set; }
}

このカスタマイズにより、 を呼び出すvar foo = fixture.Create<Foo>()と type のオブジェクトが作成されますFoo。getter を呼び出すと、foo.BarDynamicProxy と AutoFixture を使用Barしてその場で のインスタンスを作成し、そのプロパティに割り当てます。foo.Bar同じオブジェクトを返す後続の呼び出し。

注意: カスタマイズは設定するほどスマートではありませんfoo.Bar.Foo = foo- これは必要に応じて手動で行う必要があります

于 2014-05-24T08:50:53.853 に答える