@smiffy Mock the filesystem and set expectations for the write location and contents.
Best way to test file creation
I am creating a command in a package which ultimately installs a migration. What I am having trouble with is testing that the file exists and the contents of that file. I don't really want to have to physically write the file to an arbitrary location and clean up if I can help it.
My command (just the important bit):
...
use Illuminate\Filesystem\Filesystem;
...
public function construct(Filesystem $files)
{
$this->files = $files;
}
public function handle()
{
$this->files->put($location, $content);
}
...
For my test I started out mocking File which enables to check that put is called and that the call was successful but that's about it.
it('will create the migration' function() {
File::shouldReceive('put')
->once()
->andReturnTrue();
});
I'd like to be able to verify a few things in the created file to ensure the command is doing what it's supposed to be doing.
One option I have considered is to create an "On Demand" disk in my test pointing to the migrations directory (https://laravel.com/docs/9.x/filesystem#on-demand-disks ) but unsure if this is the best way. I have also seen vfstream metioned a few times, but again, unsure if this is a good fit or, more pointedly, there is a better way for Laravel. Any help on best practice appreciated!
@Smiffy You’re meant to set the expectations in that $this->mock call.
public function __construct(Filesystem $files)
{
$this->files = $files;
}
public function handle()
{
$this->files->put($location, $content);
}
$location = 'location/file/expected/to/be/saved/to';
$contents = 'Expected contents of file';
$this->mock(Filesystem::class, fn (MockInterface $mock) => $mock
->shouldReceive('put')
->once()
->with($location, $content)
->andReturnTrue()
);
$this->artisan('whatever:command')->assertSuccessful();
Please or to participate in this conversation.