I trying to test public method in service but it calls another private method.
this is a test class
<?php
use App\Core\Application\Service\Files\UploadedFileService;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use App\Core\Infrastructure\FileStorage\Services\ImagePath;
use App\Core\Infrastructure\FileStorage\Services\ImageResizeGenerator;
use Symfony\Component\Routing\RouterInterface;
class UploadedFileServiceTest extends TestCase
{
/** @var UploadedFileService */
private $instance;
private $parameterHandler;
private $router;
private $imageResizeGenerator;
private $imagePath;
public function setUp()
{
parent::setUp();
$this->parameterHandler = $this->prophesize(ParameterBagInterface::class);
$this->router = $this->prophesize(RouterInterface::class);
$this->imageResizeGenerator = $this->prophesize(ImageResizeGenerator::class);
$this->imagePath = $this->prophesize(ImagePath::class);
$this->instance = new UploadedFileService(
$this->parameterHandler->reveal(),
$this->router->reveal(),
$this->imageResizeGenerator->reveal(),
$this->imagePath->reveal()
);
}
public function testGetDefaultImageResponse()
{
$result = $this->instance->getDefaultImageResponse('user');
}
}
when I run testGetDefaultImageResponse
test, in console log error apear.
this is tested function
/**
* @param string $entity
*
* @return Response
*/
public function getDefaultImageResponse(string $entity)
{
return new Response(
$this->getDefaultImage($entity),
Response::HTTP_OK,
['Content-type' => 'image/jpg']
);
}
the real problem is in getDefaultImage()
which throw error
file_get_contents(): Filename cannot be empty
this is the content of the private method
/**
* @param string $entity
*
* @return bool|string
*/
private function getDefaultImage(string $entity)
{
switch ($entity) {
case 'entity1':
return file_get_contents($this->parameterHandler->get('images.default_avatar'));
case 'entity3':
return file_get_contents($this->parameterHandler->get('images.default_logo'));
}
return file_get_contents($this->parameterHandler->get('images.default_avatar'));
}
how to set data to $this->parameterHandler->get('images.default_avatar')
Where I mistake in running tests? I must admit that I am rookie in Unit tests.
The problem is that your test mock, in this case the ParameterHandler prophet, mocks the method get with the default behavior, returning null. It wasn't told what to do when a method is called on it, therefor file_get_contents() will not receive a file path.
First of all, you must tell your Prophet to return a proper file path:
$this->parameterHandler = $this->prophesize(ParameterBagInterface::class);
$this->parameterHandler->get('images.default_avatar')->willReturn('/your/path/avatar.jpg');
This will now tell the Prophet to return /your/path/avatar.jpg if the method get() is called with the parameter images.default_avatar. This should work, if you are able to properly configure the path to your default avatar.
You could even tell the Prophet that this method MUST be called by adding ->shouldBeCalled(), but then you would test internals of your actual tested class (there are pros and cons for that type of testing and depends on the test case):
$this->parameterHandler->get('images.default_avatar')->willReturn('/your/path/avatar.jpg')->shouldBeCalled();
The next challenge would probably be to abstract the call to file_get_contents() into a new class, which can be mocked as well (e.g. for speed and memory reasons).