在我们的上一个项目中,我们最终为我们的单元测试提供了一个共享的测试夹具,这带来了很多问题。因此,在我们当前的项目中,我研究了构建器模式。我们在开发机器的内存中运行我们的单元测试,并针对构建服务器上的数据库运行我们的单元测试。
目前我有一个 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 个导师......
或者可能创建像 WithAllCity(..)、WithAll(School) 这样的方法
有任何想法吗?我真的以正确的方式使用构建器模式吗?导演班能帮上忙吗?或者我应该从 StudentBuilder 继承类来解决这些不同的情况?
或者另一个想法,在将数据发送到数据库之前,我应该在我的服务层中添加更多验证吗?然后我会在针对内存数据库的单元测试中发现更多错误。