SparePartReservationServiceMockTest.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. <?php
  2. namespace Tests\Unit\Services;
  3. use App\Models\Reservation;
  4. use App\Models\Shortage;
  5. use App\Services\ReservationResult;
  6. use App\Services\ShortageService;
  7. use App\Services\SparePartReservationService;
  8. use Illuminate\Support\Collection;
  9. use Mockery;
  10. use Tests\TestCase;
  11. /**
  12. * Unit-тесты SparePartReservationService с Mockery-моками без реальной БД.
  13. *
  14. * Тестирует:
  15. * - Вычислительную логику ReservationResult (не требует БД)
  16. * - Корректность инстанцирования сервиса с mock ShortageService
  17. * - cancelReservation() с mock Reservation, где isActive() возвращает false
  18. */
  19. class SparePartReservationServiceMockTest extends TestCase
  20. {
  21. protected function tearDown(): void
  22. {
  23. Mockery::close();
  24. parent::tearDown();
  25. }
  26. // ==================== ReservationResult: isFullyReserved ====================
  27. public function test_reservation_result_is_fully_reserved_when_no_missing(): void
  28. {
  29. $shortage = Mockery::mock(Shortage::class);
  30. $result = new ReservationResult(
  31. reserved: 10,
  32. missing: 0,
  33. reservations: collect(),
  34. shortage: null
  35. );
  36. $this->assertTrue($result->isFullyReserved());
  37. $this->assertEquals(0, $result->missing);
  38. }
  39. // ==================== ReservationResult: hasShortage ====================
  40. public function test_reservation_result_has_shortage_when_missing_exists(): void
  41. {
  42. $shortage = Mockery::mock(Shortage::class);
  43. $result = new ReservationResult(
  44. reserved: 3,
  45. missing: 2,
  46. reservations: collect(),
  47. shortage: $shortage
  48. );
  49. $this->assertFalse($result->isFullyReserved());
  50. $this->assertTrue($result->hasShortage());
  51. $this->assertEquals(2, $result->missing);
  52. $this->assertEquals(3, $result->reserved);
  53. }
  54. // ==================== ReservationResult: getTotalRequested ====================
  55. public function test_reservation_result_get_total_requested_returns_sum(): void
  56. {
  57. $result = new ReservationResult(
  58. reserved: 7,
  59. missing: 3,
  60. reservations: collect(),
  61. shortage: null
  62. );
  63. $this->assertEquals(10, $result->getTotalRequested());
  64. }
  65. public function test_reservation_result_get_total_requested_when_fully_reserved(): void
  66. {
  67. $result = new ReservationResult(
  68. reserved: 5,
  69. missing: 0,
  70. reservations: collect(),
  71. shortage: null
  72. );
  73. $this->assertEquals(5, $result->getTotalRequested());
  74. }
  75. public function test_reservation_result_get_total_requested_when_nothing_reserved(): void
  76. {
  77. $result = new ReservationResult(
  78. reserved: 0,
  79. missing: 8,
  80. reservations: collect(),
  81. shortage: null
  82. );
  83. $this->assertEquals(8, $result->getTotalRequested());
  84. }
  85. // ==================== Service instantiation ====================
  86. public function test_service_accepts_shortage_service_dependency(): void
  87. {
  88. $shortageService = Mockery::mock(ShortageService::class);
  89. $service = new SparePartReservationService($shortageService);
  90. $this->assertInstanceOf(SparePartReservationService::class, $service);
  91. }
  92. public function test_service_can_be_instantiated_with_real_shortage_service(): void
  93. {
  94. $shortageService = new ShortageService();
  95. $service = new SparePartReservationService($shortageService);
  96. $this->assertInstanceOf(SparePartReservationService::class, $service);
  97. }
  98. // ==================== cancelReservation: non-active reservation ====================
  99. public function test_cancel_reservation_returns_false_for_non_active(): void
  100. {
  101. $shortageService = Mockery::mock(ShortageService::class);
  102. $service = new SparePartReservationService($shortageService);
  103. $reservation = Mockery::mock(Reservation::class);
  104. $reservation->shouldReceive('isActive')->once()->andReturn(false);
  105. $result = $service->cancelReservation($reservation);
  106. $this->assertFalse($result);
  107. }
  108. // ==================== ReservationResult: reservations collection ====================
  109. public function test_reservation_result_holds_reservations_collection(): void
  110. {
  111. $reservations = collect([
  112. Mockery::mock(Reservation::class),
  113. Mockery::mock(Reservation::class),
  114. ]);
  115. $result = new ReservationResult(
  116. reserved: 2,
  117. missing: 0,
  118. reservations: $reservations,
  119. shortage: null
  120. );
  121. $this->assertInstanceOf(Collection::class, $result->reservations);
  122. $this->assertCount(2, $result->reservations);
  123. $this->assertTrue($result->isFullyReserved());
  124. $this->assertFalse($result->hasShortage());
  125. }
  126. public function test_reservation_result_has_no_shortage_when_shortage_is_null(): void
  127. {
  128. $result = new ReservationResult(
  129. reserved: 5,
  130. missing: 0,
  131. reservations: collect(),
  132. shortage: null
  133. );
  134. $this->assertFalse($result->hasShortage());
  135. $this->assertNull($result->shortage);
  136. }
  137. }