我是一个相当新的Laravel,一直在阅读测试文档,但我不知道如何我会去单元测试控制器,我已经张贴在下面。任何关于我如何进行测试的建议都是非常感激的.下面的控制器是我为Booking Forms创建的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');
}
一个简单的例子:
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.comdocs7.xhttp-tests。
我也建议使用laravel Requests来验证你的表单输入,这样可以保持你的控制器的干净,并将代码放在该有的地方。关于这个主题的更多信息可以在这里找到。https:/laravel.comdocs7.xvalidation#creating-form-requests
你写的控制器有点难以测试,因为它是紧紧地耦合到 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']);
}
}
我推荐阅读Taylor Otwell的书 "Laravel从aprentice到Artisan".