Laravel Unit-тестирование - контроллеры - PullRequest
1 голос
/ 28 апреля 2020

Я довольно новичок в Laravel и читаю документацию по тестированию, однако я не уверен, как бы я go рассказал о модульном тестировании контроллера, который я опубликовал ниже. Любой совет о том, как я бы go об этом очень ценится. Ниже представлен контроллер CRUD, который я создал для форм бронирования.

class BookingFormsController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $bookingforms = BookingForm::orderBy('surgeryDate', 'asc')->paginate(5);
        return view('bookingforms.index')->with('bookingforms', $bookingforms);
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        return view('bookingforms.create');
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function store(Request $booking)
    {
      $this->validate($booking, [
      'requestID' => 'required',
      'patientID' => 'required',
      'patientForename' => 'required',
      'patientSurname'=> 'required',
      'patientSex' => 'required',
      'patientDOB' => 'required',
      'surgeryType' => 'required',
      'surgeryDate' => 'required',
      'performingSurgeon' => 'required',
      'TheatreRoomID' => 'required',
      'patientUrgency' => 'required',
      'patientNotes' => 'required',
      'bloodGroup' => 'required'
      ]);

      // Create new Booking Form
      $bookingform = new Bookingform;
      $bookingform->requestID = $booking->input('requestID');
      $bookingform->bookingID = $booking->input('bookingID');
      $bookingform->patientID = $booking->input('patientID');
      $bookingform->patientForename = $booking->input('patientForename');
      $bookingform->patientSurname = $booking->input('patientSurname');
      $bookingform->patientSex = $booking->input('patientSex');
      $bookingform->patientDOB = $booking->input('patientDOB');
      $bookingform->surgeryType = $booking->input('surgeryType');
      $bookingform->surgeryDate = $booking->input('surgeryDate');
      $bookingform->performingSurgeon = $booking->input('performingSurgeon');
      $bookingform->TheatreRoomID = $booking->input('TheatreRoomID');
      $bookingform->patientUrgency = $booking->input('patientUrgency');
      $bookingform->patientNotes = $booking->input('patientNotes');
      $bookingform->bloodGroup = $booking->input('bloodGroup');
      $bookingform->user_id = auth()->user()->id;

      //Save Booking form

      $bookingform->save();

      //redirect
      return redirect('/bookingforms')->with('success', 'Booking Submitted');
    }

    /**
     * Display the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function show($bookingID)
    {
        $bookingform = BookingForm::find($bookingID);
        return view('bookingforms.show')->with('bookingform', $bookingform);
    }

    /**
     * Show the form for editing the specified resource.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function edit($bookingID)
    {
        $bookingform = BookingForm::find($bookingID);
        //check for correct user_id
        if(auth()->user()->id !==$bookingform->user_id){
            return redirect('/bookingforms')->with('danger', 'This is not your booking, please contact the Booker.');
        }
        return view('bookingforms.edit')->with('bookingform', $bookingform);
    }

    /**
     * Update the specified resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function update(Request $booking, $bookingID)
    {
      $this->validate($booking, [
      'patientID' => 'required',
      'patientForename' => 'required',
      'patientSurname'=> 'required',
      'patientSex' => 'required',
      'patientDOB' => 'required',
      'surgeryType' => 'required',
      'surgeryDate' => 'required',
      'performingSurgeon' => 'required',
      'TheatreRoomID' => 'required',
      'patientUrgency' => 'required',
      'patientNotes' => 'required',
      'bloodGroup' => 'required'
      ]);

      // Create new Booking Form
      $bookingform = Bookingform::find($bookingID);
      $bookingform->bookingID = $booking->input('bookingID');
      $bookingform->patientID = $booking->input('patientID');
      $bookingform->patientForename = $booking->input('patientForename');
      $bookingform->patientSurname = $booking->input('patientSurname');
      $bookingform->patientSex = $booking->input('patientSex');
      $bookingform->patientDOB = $booking->input('patientDOB');
      $bookingform->surgeryType = $booking->input('surgeryType');
      $bookingform->surgeryDate = $booking->input('surgeryDate');
      $bookingform->performingSurgeon = $booking->input('performingSurgeon');
      $bookingform->TheatreRoomID = $booking->input('TheatreRoomID');
      $bookingform->patientUrgency = $booking->input('patientUrgency');
      $bookingform->patientNotes = $booking->input('patientNotes');
      $bookingform->bloodGroup = $booking->input('bloodGroup');
      $bookingform->user_id = auth()->user()->id;

      //Save Booking form

      $bookingform->save();

      //redirect
      return redirect('/bookingforms')->with('success', 'Booking Updated');

    }

    /**
     * Remove the specified resource from storage.
     *
     * @param  int  $id
     * @return \Illuminate\Http\Response
     */
    public function destroy($bookingID)
    {
        $bookingform = Bookingform::find($bookingID);
        if(auth()->user()->id !==$bookingform->user_id){
            return redirect('/bookingforms')->with('danger', 'This is not your booking, please contact the Booker.');
        }
        $bookingform->delete();
        return redirect('/bookingforms')->with('success', 'Booking Removed');
    }

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Контроллер, который вы написали, немного сложен для тестирования, так как он тесно связан с моделью Eloquent. Вам лучше отделить его, добавив слой репозитория и вставить его в свой контроллер.

Кстати: вы можете использовать атрибутов , чтобы избежать написания большого количества кода, просто чтобы заполнить атрибуты вашего BookingForm

Теперь, например, вы можете сделать следующее:

Создать интерфейс BookingFormRepository:

interface BookingFormRepository
{
    public function all();
    public function create(array $attributes);

    // etc ....

}

Создать реализацию BookingFormRepository:

class BookingFormRepositoryImpl implements BookingRepository 
{
    public function all()
    {
         return BookingForm::all();
    }

    public function create(array $attributes)
    {
        // Use fillable attributes for better readability
        $record = BookingForm::create($attributes);
        return $record;
    }

    // Implement other methods ....
}

В AppServiceProvider в методе register свяжите свою реализацию:

App::bind(BookingFormRepository::class, BookingFormRepositoryImpl::class); 

Затем в свой контроллер введите интерфейс BookingRepository:

class BookingFormController extends Controller {

    private $bookingFormRepository;

    public function __construct(BookingFormRepository $bookingRepo)
    {
        $this->bookingFormRepository = $bookingRepo;
    }

    public function index()
    {
        $bookings = $this->bookingFormRepository->all();
        return view('bookingform.index', $bookings);
    }

    // .. other methods ... like `store`
}

Теперь контроллер будет легко тестировать, просто смоделируйте BookingRepository и сделайте на нем утверждения вызова:

class BookingFormControllerTest extends TestCase
{
     public function testIndexBookingForm()
     {
          // Arrange

          $repository = Mockery::mock('BookingRepository');
          $repository->shouldReceive('all')->once()
              ->andReturn(['foobar']);
          App::instance('BookingRepository', $repository);


          // Act, Replace with your right url ...
          $this->get('bookings');

          // Assert
          $this->assertResponseOk();
          $this->assertViewHas('bookingforms.index', ['foobar']);
     }
}

Я рекомендую прочитать книгу Тейлора Отвелла "Laravel от ученика до Ремесленника".

0 голосов
/ 28 апреля 2020

Простой пример:

class ExampleTest extends TestCase
{
    public function testBookingFormsIndex()
    {
        $response = $this->get('index');
        $response->assertStatus('200');
    }

    public function testBookingFormsCreate()
    {
        $response = $this->get('create');
        $response->assertStatus('200');
    }

}

Как я уже сказал, выше приведен базовый c пример, основанный на примере из документации HTTP Test из laravel.

Более подробную информацию можно найти здесь: https://laravel.com/docs/7.x/http-tests

Я также рекомендовал бы использовать laravel Запросы для проверки ввода формы, это поддерживает ваш контроллер в чистоте и размещает код где принадлежит. Более подробную информацию об этом топи c можно найти здесь: https://laravel.com/docs/7.x/validation#creating -form-запросы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...