Feb 2, 2024
0
Level 1
Trying to know Best Practices of Laravel unit tests
Hey. In a project, beside feature tests I had some unit tests that was testing of my laravel service class given below:
PostService.php
<?php
namespace App\Services;
use App\Constants\MediaCollectionName;
use App\Models\Post;
use Illuminate\Support\Facades\DB;
class PostService
{
public function store(array $data, $image = null)
{
return DB::transaction(function () use ($data, $image) {
$post = auth()->user()->posts()->create($data);
if ($image) {
$post
->addMedia($image)
->toMediaCollection(MediaCollectionName::POST_IMAGE);
}
return $post;
}, 3);
}
public function update(Post $post, array $data, $image = null)
{
return DB::transaction(function () use ($post, $data, $image) {
$post->update($data);
if ($image) {
$post
->addMedia($image)
->toMediaCollection(MediaCollectionName::POST_IMAGE);
}
return $post;
}, 3);
}
}
PostServiceTest.php
<?php
namespace Tests\Unit\Services;
use App\Models\Post;
use App\Services\PostService;
use Illuminate\Http\UploadedFile;
use PHPUnit\Framework\TestCase;
use Illuminate\Support\Facades\DB;
class PostServiceTest extends TestCase
{
public $postMock;
public function setUp(): void
{
parent::setUp();
$this->postMock = $this->createMock(Post::class);
}
public function test_store_method()
{
DB::shouldReceive('transaction')
->once()
->andReturn($this->postMock);
$result = resolve(PostService::class)->store([
'body' => 'A new post',
]);
$this->assertInstanceOf(Post::class, $result);
}
public function test_store_method_with_image()
{
DB::shouldReceive('transaction')
->once()
->andReturn($this->postMock);
$image = UploadedFile::fake()->image('image.png');
$result = resolve(PostService::class)->store(
[
'body' => 'A new post',
],
$image,
);
$this->assertInstanceOf(Post::class, $result);
}
public function test_store_method_with_incorrect_parameters()
{
$this->expectException('TypeError');
resolve(PostService::class)->store('data');
}
public function test_update_method()
{
DB::shouldReceive('transaction')
->once()
->andReturn($this->postMock);
$result = resolve(PostService::class)->update(
$this->postMock,
[
'body' => 'Updated post',
],
);
$this->assertInstanceOf(Post::class, $result);
}
public function test_update_method_with_image()
{
DB::shouldReceive('transaction')
->once()
->andReturn($this->postMock);
$image = UploadedFile::fake()->image('image.png');
$result = resolve(PostService::class)->update(
$this->postMock,
[
'body' => 'Updated post',
],
$image,
);
$this->assertInstanceOf(Post::class, $result);
}
public function test_update_method_with_incorrect_parameters()
{
$this->expectException('TypeError');
resolve(PostService::class)->update('data');
}
}
But problem is: someone suggest me your feature tests are ok, but unit tests might be improved and not should be like that. But I have no idea why he said it like that, and which best practices should I follow in order to write good unit test rather than given????
Somebody help me to know the best practices of laravel unit test...
Please or to participate in this conversation.