getMockBuilder(HasMany::class) ->disableOriginalConstructor() ->onlyMethods(['__call']) ->getMock(); $mockBuilder = $this->getMockBuilder(Builder::class) ->disableOriginalConstructor() ->getMock(); $mockBuilder->method('get')->willReturn($contracts); $mockRelation->method('__call') ->with('latestVersion', []) ->willReturn($mockBuilder); $student = new class($mockRelation) extends Student { private $mockRelation; public function __construct($mockRelation = null) { parent::__construct(); if ($mockRelation) { $this->mockRelation = $mockRelation; } } public function contracts(): HasMany { return $this->mockRelation; } }; return $student; } public function test_student_without_contracts_is_lead(): void { $student = $this->createStudentWithContracts(collect([])); $this->assertSame(Student::STATUS_LEAD, $student->calculateStatus()); } public function test_student_with_active_contract_in_future_is_active(): void { $contract = new StudentContract; $contract->status = 'active'; $contract->end_date = Carbon::now()->addDays(10); $student = $this->createStudentWithContracts(collect([$contract])); $this->assertSame(Student::STATUS_ACTIVE, $student->calculateStatus()); } public function test_student_with_active_contract_in_past_is_ex_student(): void { $contract = new StudentContract; $contract->status = 'active'; $contract->end_date = Carbon::now()->subDays(10); // Expired $student = $this->createStudentWithContracts(collect([$contract])); $this->assertSame(Student::STATUS_EX_STUDENT, $student->calculateStatus()); } public function test_student_with_frozen_contract_and_no_active_is_locked(): void { $contract = new StudentContract; $contract->status = 'frozen'; $contract->end_date = Carbon::now()->addDays(10); $student = $this->createStudentWithContracts(collect([$contract])); $this->assertSame(Student::STATUS_LOCKED, $student->calculateStatus()); } public function test_student_with_cancelled_contracts_only_is_ex_student(): void { $contract = new StudentContract; $contract->status = 'cancelled'; $contract->end_date = Carbon::now()->addDays(10); $student = $this->createStudentWithContracts(collect([$contract])); $this->assertSame(Student::STATUS_EX_STUDENT, $student->calculateStatus()); } }