academia/tests/Common/Builders/StudentBuilder.cs

79 lines
2.1 KiB
C#
Raw Normal View History

namespace Common.Builders;
using Domain.Entities;
using Domain.ValueObjects;
/// <summary>
/// Builder pattern for creating Student test objects.
/// Encapsulates reflection-based ID setting for cleaner tests.
/// </summary>
public class StudentBuilder
{
private int _id = 1;
private string _name = "John Doe";
private string _email = "john@test.com";
private readonly List<(Subject Subject, int EnrollmentId)> _enrollments = [];
public StudentBuilder WithId(int id)
{
_id = id;
return this;
}
public StudentBuilder WithName(string name)
{
_name = name;
return this;
}
public StudentBuilder WithEmail(string email)
{
_email = email;
return this;
}
public StudentBuilder WithEnrollment(Subject subject, int enrollmentId = 0)
{
_enrollments.Add((subject, enrollmentId));
return this;
}
public StudentBuilder WithEnrollments(int count)
{
for (int i = 0; i < count; i++)
{
var subject = new SubjectBuilder()
.WithId(i + 100)
.WithName($"Subject{i}")
.WithProfessorId(i + 1)
.WithProfessor(new ProfessorBuilder()
.WithId(i + 1)
.WithName($"Prof{i}")
.Build())
.Build();
_enrollments.Add((subject, i + 1));
}
return this;
}
public Student Build()
{
var student = new Student(_name, Email.Create(_email));
SetProperty(student, "Id", _id);
foreach (var (subject, enrollmentId) in _enrollments)
{
var enrollment = new Enrollment(student.Id, subject.Id);
if (enrollmentId > 0)
SetProperty(enrollment, "Id", enrollmentId);
SetProperty(enrollment, "Subject", subject);
student.AddEnrollment(enrollment);
}
return student;
}
private static void SetProperty<T>(T obj, string propertyName, object value) where T : class =>
typeof(T).GetProperty(propertyName)!.SetValue(obj, value);
}