5

前回のプロジェクトでは、ユニット テスト用の共有テスト フィクスチャが発生し、多くの問題が発生しました。そのため、現在のプロジェクトではビルダー パターンを調べました。単体テストは、開発マシンのメモリ内で実行し、ビルド サーバーのデータベースに対して実行します。

現在、たとえば学生用に次のビルダーを生成する T4 テンプレートがあります。

public class StudentBuilder : Builder<Student, StudentBuilder>
{
    public StudentBuilder()
    {
        IsMale = true;
    }

    public StudentBuilder WithFirstName(string firstName)
    {
        this.FirstName = firstName;
        return this;
    }

    public StudentBuilder WithLastName(string lastName)
    {
        this.LastName = lastName;
        return this;
    }

    public StudentBuilder WithIsMale(bool isMale)
    {
        this.IsMale = isMale;
        return this;
    }

    internal override Student Construct()
    {
        Student result = new Student()
        {
            FirstName = FirstName ?? "FirstName:" + id.ToString(),
            LastName = LastName ?? "LastName:" + id.ToString(),
            IsMale = IsMale,
            Id = id,
        };

     /   return result;
    }
}

基本クラスを通じて、これを次のように使用できます。

Student wouter = StudentBuilder.Build()
    .WithFirstName("Wouter")
    .WithLastName("de Kort");
List<Student> students = StudentBuilder.Build().Multiple(10, (builder, index) => builder.WithFirstName("FirstName" + index));

ビルド サーバーで統合テストを実行して、すべてがデータベースに対して機能することを確認します。これは、すべての参照制約が満たされていることを確認する必要があることを意味します。しかし、問題が始まります。

たとえば、学生にはメンターが必要であり、メンターは学校に所属し、学校は都市に、都市は ....

これにより、次のようなコードが生成されます。

StudentBuilder.Build().WithMentor(MentorBuilder.Build().WithSchool(SchoolBuilder.Build().WithCity(CityBuilder.Build()))

これをどのように最適化すればよいですか?各 Builder の Construct メソッドで「デフォルトの建物」を作成することを考えましたが、10 人の生徒を作成すると、10 都市の 10 の学校に 10 人のメンターが 10 人いることになります。

または、WithAllCity(..)、WithAll(School) などのメソッドを作成することもできます。

何か案は?Builder パターンを実際に正しい方法で使用していますか? ディレクタークラスは役に立ちますか? または、これらのさまざまなケースを解決する StudentBuilder からクラスを継承する必要がありますか?

または別のアイデアとして、データをデータベースに送信する前に、サービス層にさらに検証を追加する必要がありますか? 次に、メモリ内データベースに対する単体テストでより多くのエラーを検出します。

4

2 に答える 2

1

単体テストで生徒のメンター、メンターの学校、および学校の​​都市を使用する場合、単体テストでそのすべてを構築するコードを使用することは合理的だと思いますが、単体テストがテストではない可能性があることをお勧めしますたったひとつ。単体テストをより具体的にして、非常に多くのプロパティをドリルダウンしないようにします。

問題が単体テストではなく、学生クラスがメンターをコンストラクターにフィードすることを要求し、そのメンターを null にできない場合は、null メンターを許可するようにその要件を緩和することを検討してください (私の好みだと思います)。あなたが言うように、ビルダーは「デフォルト」オブジェクトを埋めます。プロパティにアクセスしようとすると、既定のオブジェクトに例外をスローさせることもできます。これにより、単体テストで「実際の」オブジェクトを作成する必要があることが通知されます。

于 2011-11-09T09:29:29.357 に答える