【发布时间】:2021-06-03 04:16:23
【问题描述】:
我有一个 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;
}
}
我正在尝试将getParentId() 测试为:
<?php
namespace App\Test\Unit;
use PHPUnit\Framework\TestCase;
use App\Model\ParentIdResolver;
use App\Model\Product\Bundle;
use App\Model\Product\Configurable;
use App\Model\Product\Downloadable;
class ParentIdResolverTest extends TestCase
{
protected $model;
protected $bundleMock;
protected $configurableMock;
protected $downloadableMock;
public function setUp(): void
{
$this->bundleMock = $this->createPartialMock(
Bundle::class,
['getParentIdsByChild']
);
$this->configurableMock = $this->createPartialMock(
Configurable::class,
['getParentIdsByChild']
);
$this->downloadableMock = $this->createPartialMock(
Downloadable::class,
['getParentIdsByChild']
);
$this->model = new ParentIdResolver(
$this->bundleMock,
$this->configurableMock,
$this->downloadableMock
);
}
/**
* @dataProvider getParentIdDataProvider
*/
public function testGetParentId($productId, $productType, $parentId)
{
if ($productType == 'bundle') {
$this->bundleMock->expects($this->any())
->method('getParentIdsByChild')
->willReturn([$parentId]);
}
if ($productType == 'configurable') {
$this->configurableMock->expects($this->any())
->method('getParentIdsByChild')
->willReturn([$parentId]);
}
if ($productType == 'downloadable') {
$this->downloadableMock->expects($this->any())
->method('getParentIdsByChild')
->willReturn([$parentId]);
}
$this->assertEquals($parentId, $this->model->getParentId($productId, $productType));
}
public function getParentIdDataProvider()
{
return [
[1, 'bundle', 11],
[2, 'configurable', 22],
[3, 'downloadable', 33],
];
}
}
而且我觉得我做的不正确,也许我需要重构主类?
请建议在这种情况下您将如何重构或编写单元测试。
【问题讨论】:
-
如果测试成功并且代码有效,这将是Code review的更好候选者。
-
@El_Vanja 写得好!
-
您可以从测试中删除所有
if语句,并立即模拟每个案例。这样测试会更简洁 -
@PtrTon 是的,这是重构单元测试的另一种选择。但是关于重构主类?你觉得有什么改进的余地吗?
-
我给你留下了更详细的方法here
标签: php unit-testing phpunit tdd