前回のプロジェクトでは、ユニット テスト用の共有テスト フィクスチャが発生し、多くの問題が発生しました。そのため、現在のプロジェクトではビルダー パターンを調べました。単体テストは、開発マシンのメモリ内で実行し、ビルド サーバーのデータベースに対して実行します。
現在、たとえば学生用に次のビルダーを生成する 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 からクラスを継承する必要がありますか?
または別のアイデアとして、データをデータベースに送信する前に、サービス層にさらに検証を追加する必要がありますか? 次に、メモリ内データベースに対する単体テストでより多くのエラーを検出します。