我对Laravel并不陌生,并且一直在阅读有关测试的文档,但是我不确定如何对下面发布的控制器进行单元测试。非常感谢任何关于我将如何解决此问题的建议。 下面的控制器是我为预订表格创建的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');
}
答案 0 :(得分:0)
一个简单的例子:
class ExampleTest extends TestCase
{
public function testBookingFormsIndex()
{
$response = $this->get('index');
$response->assertStatus('200');
}
public function testBookingFormsCreate()
{
$response = $this->get('create');
$response->assertStatus('200');
}
}
就像我说的那样,以上是一个基本示例,该示例基于laravel的HTTP测试文档中的示例。
更多信息可以在这里找到: https://laravel.com/docs/7.x/http-tests
我还建议您使用laravel请求来验证您的表单输入,这样可以使您的控制器保持整洁并将代码放置在所属位置。 有关此主题的更多信息,请参见:https://laravel.com/docs/7.x/validation#creating-form-requests
答案 1 :(得分:0)
您编写的控制器有点难以测试,因为它与Eloquent
模型紧密耦合。您最好通过添加存储库层将其解耦并将其注入到控制器中。
顺便说一句:您可以使用fillable attributes来避免编写大量代码来填充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']);
}
}
我建议阅读泰勒·奥特威尔(Taylor Otwell)的书“从学徒到工匠的拉拉威尔(Laravel)”。