I am trying to write a test for the following Livewire component that uploads an image:
use Livewire\Component;
use Livewire\WithFileUploads;
class UploadImage extends Component
{
use WithFileUploads;
public $image;
public function save()
{
$this->validate([
'image' => 'image|mimes:jpg,jpeg',
]);
$storedImage = $this->image->store('images'); // returns e.g. "images/PznpCCFUUDjZuZRDEAGpsr7SxV2qIM2dEsZ3l0zO.jpeg"
// save $storedImage as the name in the images table
}
}
The test below fails because the file is saved to the disk and db with the hashed name and not test.jpg
. How do I get the hashed name that was created by Livewire for the image in the test?
The $storedImage
in the component is not the same as the $image->hashName()
in the test
/** @test **/
function it_can_upload_an_image() {
Storage::fake();
$image = UploadedFile::fake()->image('test.jpeg');
Livewire::test(UploadImage::class)
->set('image', $image)
->call('save');
$this->assertDatabaseHas('images', [
'name' => "images/{$image->hashName()}",
]);
Storage::assertExists("images/{$image->hashName()}");
}
I found the answer in the source code's tests here. The solution is so simple 🤦♂️
Add a public property to the component for the $storedImage
so that it can be accessed in the tests.
e.g.
use Livewire\Component;
use Livewire\WithFileUploads;
class UploadImage extends Component
{
use WithFileUploads;
public $image;
public $storedImage;
public function save()
{
$this->validate([
'image' => 'image|mimes:jpg,jpeg',
]);
$this->storedImage = $this->image->store('images');
// save $storedImage as the name in the images table
}
}
Now the hashed name can be accessed from the test like:
/** @test **/
function it_can_upload_an_image() {
Storage::fake();
$image = UploadedFile::fake()->image('test.jpeg');
$storedImage = Livewire::test(UploadImage::class)
->set('image', $image)
->call('save')
->get('storedImage');
$this->assertDatabaseHas('images', [
'name' => $storedImage,
]);
Storage::assertExists($storedImage);
}