在单元测试中传递参数,在数据库 CRUD 中更新函数 Laravel
Passing parameters in an Unit Test, function update in database CRUD Laravel
我一直在创建一些测试来尝试从我的数据库中在 laravel 上创建删除编辑功能,这是我的代码:
ConstituencyController.php :
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreConstituencyRequest;
use App\Http\Resources\ConstituencyResource;
use App\Models\Constituency;
use Illuminate\Http\Request;
use phpDocumentor\Reflection\Types\Collection;
class ConstituencyController extends Controller
{
/**
* Display a listing of the constituencies.
*
*
*/
public function index()
{
$constituency = Constituency::all();
return ConstituencyResource::collection($constituency);
}
/**
* Show the form for creating a new resource.
*
*
*/
public function create()
{
//
}
/**
* Store a newly created constituency in storage.
*
* @param Request $request
*
*/
public function store(Request $request)
{
$name = $request->name;
$data = array("name"=>$name);
Constituency::insert($data);
}
/**
* Display the specified constituency.
*
* @param int $id
*
*/
public function show(int $id)
{
$constituency = Constituency::find($id);
return new ConstituencyResource($constituency);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
*
*/
public function edit(int $id)
{
//
}
/**
* Update the specified constituency in storage.
*
* @param Request $request
* @param int $id
*
*/
public function update(Request $request, int $id)
{
$constituency = Constituency::find($id);
$constituency->name = $request->name;
$constituency->update();
}
/**
* Remove the specified constituency from storage.
*
* @param int $id
*
*/
public function destroy(int $id)
{
Constituency::find($id)->delete();
}
}
Constituency.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Constituency extends Model
{
use HasFactory;
public function candidate()
{
return $this->hasMany(Candidate::class);
}
public function town()
{
return $this->hasMany(Town::class);
}
}
ConstituencyResource.php :
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ConstituencyResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
ConstituencyFactory.php :
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Constituency>
*/
class ConstituencyFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'name' => $this->faker->word(),
];
}
}
现在这是我更新选区的测试:
public function test_a_constituency_can_be_modified()
{
$constituency = Constituency::factory()->create();
$constituency_id = $constituency->id;
$response = $this->put('api/constituencies/'.$constituency_id);
$this->assertDatabaseHas('constituencies', [
'id' => $constituency->id,
'name' => $constituency->name,
'created_at' => $constituency->created_at,
'updated_at' => $constituency->updated_at,
]);
}
现在当然测试通过了,但我实际上并没有给它一些新的参数来改变...我一直在尝试给函数一些参数来实际改变一些数据,但我不能弄清楚该怎么做....我认为我不必将参数放在 URI 中,但那又在哪里呢?
如果您正在使用 PHPUnit you likely want to make use of Data Providers:
来自文档的示例
/**
* @dataProvider additionProvider
*/
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertSame($expected, $a + $b);
}
public function additionProvider(): array
{
return [
'adding zeros' => [0, 0, 0],
'zero plus one' => [0, 1, 1],
'one plus zero' => [1, 0, 1],
'one plus one' => [1, 1, 3]
];
}
Tighten 的聪明人也有 excellent tutorial on data providers。
如果您正在使用 PEST then you'll want Data Sets。
来自文档的示例
dataset('emails', [
'enunomaduro@gmail.com',
'other@example.com'
]);
it('has emails', function ($email) {
expect($email)->not->toBeEmpty();
})->with('emails'); // <-- use the dataset
使用数据提供者和数据集可以让您重复使用数据,还可以针对单元测试的多个输入进行测试。如果您只想在排列语句(创建数据库记录的位置)后硬编码一个值,那么您可以这样做,但这样做有局限性,而且提供程序要灵活得多。
更新 - 示例测试
以下是您可能如何处理事情的示例。请注意,这并不详尽,并且不建议使用 $request->all()
来更新您的模型,但我这样做是为了使事情简单明了。这应该让您了解 where/how 您可以着手执行测试。这样的事情有很多ways/opinions
api.php
Route::put('/constituencies/{constituency}',
[ConstituencyController::class, 'update']
)->name('api.constituencies.update');
ConstituencyController.php
<?php
namespace App\Http\Controllers;
use App\Models\Constituency;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ConstituencyController extends Controller
{
public function update(Request $request, Constituency $constituency)
{
$constituency->update($request->all());
return response()->json($constituency, Response::HTTP_OK);
}
}
ExampleTest.php
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Constituency;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @test
* @dataProvider constituencyNameProvider
* @return void
*/
public function it_can_update_constituency_name_successfully($constituencyName)
{
// Arrange
$constituency = Constituency::factory()->create();
$payload = ['name' => $constituencyName];
// Act
$response = $this->put(route('api.constituencies.update', $constituency->id), $payload);
// Assert
$response->assertStatus(Response::HTTP_OK)
->assertJson([
'id' => $constituency->id,
'name' => $constituencyName
])
->assertJsonStructure([
'id', 'name', 'created_at', 'updated_at'
]);
}
public function constituencyNameProvider(): array
{
return [
['Ostwald'],
['Springtown'],
['Baybarrow'],
['Blackhaven'],
['Lochspring'],
];
}
}
我一直在创建一些测试来尝试从我的数据库中在 laravel 上创建删除编辑功能,这是我的代码:
ConstituencyController.php :
<?php
namespace App\Http\Controllers;
use App\Http\Requests\StoreConstituencyRequest;
use App\Http\Resources\ConstituencyResource;
use App\Models\Constituency;
use Illuminate\Http\Request;
use phpDocumentor\Reflection\Types\Collection;
class ConstituencyController extends Controller
{
/**
* Display a listing of the constituencies.
*
*
*/
public function index()
{
$constituency = Constituency::all();
return ConstituencyResource::collection($constituency);
}
/**
* Show the form for creating a new resource.
*
*
*/
public function create()
{
//
}
/**
* Store a newly created constituency in storage.
*
* @param Request $request
*
*/
public function store(Request $request)
{
$name = $request->name;
$data = array("name"=>$name);
Constituency::insert($data);
}
/**
* Display the specified constituency.
*
* @param int $id
*
*/
public function show(int $id)
{
$constituency = Constituency::find($id);
return new ConstituencyResource($constituency);
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
*
*/
public function edit(int $id)
{
//
}
/**
* Update the specified constituency in storage.
*
* @param Request $request
* @param int $id
*
*/
public function update(Request $request, int $id)
{
$constituency = Constituency::find($id);
$constituency->name = $request->name;
$constituency->update();
}
/**
* Remove the specified constituency from storage.
*
* @param int $id
*
*/
public function destroy(int $id)
{
Constituency::find($id)->delete();
}
}
Constituency.php:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Constituency extends Model
{
use HasFactory;
public function candidate()
{
return $this->hasMany(Candidate::class);
}
public function town()
{
return $this->hasMany(Town::class);
}
}
ConstituencyResource.php :
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class ConstituencyResource extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
*/
public function toArray($request)
{
return [
'id' => $this->id,
'name' => $this->name,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
];
}
}
ConstituencyFactory.php :
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Constituency>
*/
class ConstituencyFactory extends Factory
{
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition()
{
return [
'name' => $this->faker->word(),
];
}
}
现在这是我更新选区的测试:
public function test_a_constituency_can_be_modified()
{
$constituency = Constituency::factory()->create();
$constituency_id = $constituency->id;
$response = $this->put('api/constituencies/'.$constituency_id);
$this->assertDatabaseHas('constituencies', [
'id' => $constituency->id,
'name' => $constituency->name,
'created_at' => $constituency->created_at,
'updated_at' => $constituency->updated_at,
]);
}
现在当然测试通过了,但我实际上并没有给它一些新的参数来改变...我一直在尝试给函数一些参数来实际改变一些数据,但我不能弄清楚该怎么做....我认为我不必将参数放在 URI 中,但那又在哪里呢?
如果您正在使用 PHPUnit you likely want to make use of Data Providers:
来自文档的示例
/**
* @dataProvider additionProvider
*/
public function testAdd(int $a, int $b, int $expected): void
{
$this->assertSame($expected, $a + $b);
}
public function additionProvider(): array
{
return [
'adding zeros' => [0, 0, 0],
'zero plus one' => [0, 1, 1],
'one plus zero' => [1, 0, 1],
'one plus one' => [1, 1, 3]
];
}
Tighten 的聪明人也有 excellent tutorial on data providers。
如果您正在使用 PEST then you'll want Data Sets。
来自文档的示例
dataset('emails', [
'enunomaduro@gmail.com',
'other@example.com'
]);
it('has emails', function ($email) {
expect($email)->not->toBeEmpty();
})->with('emails'); // <-- use the dataset
使用数据提供者和数据集可以让您重复使用数据,还可以针对单元测试的多个输入进行测试。如果您只想在排列语句(创建数据库记录的位置)后硬编码一个值,那么您可以这样做,但这样做有局限性,而且提供程序要灵活得多。
更新 - 示例测试
以下是您可能如何处理事情的示例。请注意,这并不详尽,并且不建议使用 $request->all()
来更新您的模型,但我这样做是为了使事情简单明了。这应该让您了解 where/how 您可以着手执行测试。这样的事情有很多ways/opinions
api.php
Route::put('/constituencies/{constituency}',
[ConstituencyController::class, 'update']
)->name('api.constituencies.update');
ConstituencyController.php
<?php
namespace App\Http\Controllers;
use App\Models\Constituency;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class ConstituencyController extends Controller
{
public function update(Request $request, Constituency $constituency)
{
$constituency->update($request->all());
return response()->json($constituency, Response::HTTP_OK);
}
}
ExampleTest.php
<?php
namespace Tests\Feature;
use Tests\TestCase;
use App\Models\Constituency;
use Symfony\Component\HttpFoundation\Response;
use Illuminate\Foundation\Testing\RefreshDatabase;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* @test
* @dataProvider constituencyNameProvider
* @return void
*/
public function it_can_update_constituency_name_successfully($constituencyName)
{
// Arrange
$constituency = Constituency::factory()->create();
$payload = ['name' => $constituencyName];
// Act
$response = $this->put(route('api.constituencies.update', $constituency->id), $payload);
// Assert
$response->assertStatus(Response::HTTP_OK)
->assertJson([
'id' => $constituency->id,
'name' => $constituencyName
])
->assertJsonStructure([
'id', 'name', 'created_at', 'updated_at'
]);
}
public function constituencyNameProvider(): array
{
return [
['Ostwald'],
['Springtown'],
['Baybarrow'],
['Blackhaven'],
['Lochspring'],
];
}
}