Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHPUnit:如何对多个if-else/工厂进行单元测试?_Php_Unit Testing_Phpunit_Tdd - Fatal编程技术网

PHPUnit:如何对多个if-else/工厂进行单元测试?

PHPUnit:如何对多个if-else/工厂进行单元测试?,php,unit-testing,phpunit,tdd,Php,Unit Testing,Phpunit,Tdd,我有一个类ParentIdResolver,它根据类型返回产品的父id。 该类看起来像: <?php namespace App\Model; use App\Model\Product\Bundle; use App\Model\Product\Configurable; use App\Model\Product\Downloadable; class ParentIdResolver { /** * @var Bundle */ privat

我有一个类
ParentIdResolver
,它根据类型返回产品的父id。
该类看起来像:

<?php

namespace App\Model;

use App\Model\Product\Bundle;
use App\Model\Product\Configurable;
use App\Model\Product\Downloadable;

class ParentIdResolver
{
    /**
     * @var Bundle
     */
    private $bundle;
    /**
     * @var Configurable
     */
    private $configurable;
    /**
     * @var Downloadable
     */
    private $downloadable;

    public function __construct(
        Bundle $bundle,
        Configurable $configurable,
        Downloadable $downloadable
    ) {
        $this->bundle = $bundle;
        $this->configurable = $configurable;
        $this->downloadable = $downloadable;
    }

    public function getParentId($productId, $productType)
    {
        $parentIds = [];
        if ($productType == 'bundle') {
            $parentIds = $this->bundle->getParentIdsByChild($productId);
        } elseif ($productType == 'configurable') {
            $parentIds = $this->configurable->getParentIdsByChild($productId);
        } elseif ($productType == 'downloadable') {
            $parentIds = $this->downloadable->getParentIdsByChild($productId);
        }
        return $parentIds[0] ?? null;
    }
}
我觉得我做得不对,也许我需要重构主类?

请说明在这种情况下,您将如何重构或编写单元测试。有些人会称之为“问,不要说”。看起来像这样

<?php

namespace App\Model;

use App\Model\Product\ResolvesParentId;

class ParentIdResolver
{
    /** @var ResolvesParentId[] */
    private $parentIdResolvers;

    public function __construct(array $parentIdResolvers)
    {
        $this->parentIdResolvers = $parentIdResolvers;
    }

    public function getParentId(int $productId, string $productType): int
    {
        foreach ($this->parentIdResolvers as $parentIdResolver) {
            if ($parentIdResolver->supports($productType)) {
                return $parentIdResolver->getParentId($productId)[0] ?? null;
            }
        }

        return null;
    }
}

如果测试成功并且代码正常工作,这将是一个更好的选择。@El_Vanja注意到了!您可以立即从测试和模拟中删除所有
if
语句。测试将更加简洁way@PtrTon是的,这是重构单元测试的另一个选择。但是关于重构主类呢?你认为还有改进的余地吗?我给你留下了一个更详细的方法你是说“告诉,不要问”的TDA方法?现在我觉得一直出错很傻:)你会怎么使用它#用法?将包含
捆绑包
可配置
可下载
实例的数组注入
ParentIdResolver
。然后在该数组中查找正确的实现,并基于它解析父id
<?php

namespace App\Model;

use App\Model\Product\ResolvesParentId;

class ParentIdResolver
{
    /** @var ResolvesParentId[] */
    private $parentIdResolvers;

    public function __construct(array $parentIdResolvers)
    {
        $this->parentIdResolvers = $parentIdResolvers;
    }

    public function getParentId(int $productId, string $productType): int
    {
        foreach ($this->parentIdResolvers as $parentIdResolver) {
            if ($parentIdResolver->supports($productType)) {
                return $parentIdResolver->getParentId($productId)[0] ?? null;
            }
        }

        return null;
    }
}
<?php

namespace App\Model\Product;

interface ResolvesParentId
{
    public function supports(string $productType): bool;

    public function getParentIdsByChild(int $productId): array;
}
<?php

namespace App\Model\Product;

class Bundle implements ResolvesParentId
{
    public function supports(string $productType): bool
    {
        return $productType === 'bundle';
    }

    public function getParentIdsByChild(int $productId): array
    {
        // Your implementation here.
    }
}
<?php

namespace App\Model\Product;

class Configurable implements ResolvesParentId
{
    public function supports(string $productType): bool
    {
        return $productType === 'configurable';
    }

    public function getParentIdsByChild(int $productId): array
    {
        // Your implementation here.
    }
}
<?php

namespace App\Model\Product;

class Downloadable implements ResolvesParentId
{
    public function supports(string $productType): bool
    {
        return $productType === 'downloadable';
    }

    public function getParentIdsByChild(int $productId): array
    {
        // Your implementation here.
    }
}