0

我试图在服务中测试公共方法,但它调用了另一个私有方法。

这是一个测试课

<?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');
    }

}

当我运行testGetDefaultImageResponse测试时,在控制台日志中出现错误。

这是经过测试的功能

/**
 * @param string $entity
 *
 * @return Response
 */
public function getDefaultImageResponse(string $entity)
{
    return new Response(
        $this->getDefaultImage($entity),
        Response::HTTP_OK,
        ['Content-type' => 'image/jpg']
    );
}

真正的问题是getDefaultImage() 抛出错误

file_get_contents():文件名不能为空

这是私有方法的内容

/**
 * @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'));
}

如何将数据设置为$this->parameterHandler->get('images.default_avatar')

我在运行测试时出错的地方?我必须承认我是单元测试的新手。

4

1 回答 1

1

问题是您的测试模拟,在本例中为ParameterHandler预言机,以默认行为模拟get方法,返回 null。当一个方法被调用时,它没有被告知要做什么,因此file_get_contents()不会收到文件路径。

首先,你必须告诉你的 Prophet 返回一个正确的文件路径:

    $this->parameterHandler = $this->prophesize(ParameterBagInterface::class);
    $this->parameterHandler->get('images.default_avatar')->willReturn('/your/path/avatar.jpg');

现在,如果使用参数 images.default_avatar 调用方法get (),这将告诉 Prophet 返回/your/path/avatar.jpg。如果您能够正确配置默认头像的路径,这应该可以工作。

你甚至可以告诉 Prophet 这个方法必须通过添加->shouldBeCalled()来调用,但是你会测试你实际测试的类的内部(这种类型的测试有优缺点,取决于测试用例):

    $this->parameterHandler->get('images.default_avatar')->willReturn('/your/path/avatar.jpg')->shouldBeCalled();

下一个挑战可能是将对file_get_contents()的调用抽象为一个新类,该类也可以被模拟(例如,出于速度和内存原因)。

于 2018-11-03T11:58:57.730 回答