我在PHP中有一个简单的类,没有依赖项注入。
我想知道一种避免在测试中使用new History()
对其进行模拟的最佳实践。
所以我的目标是使History
是可模拟的。
这是我的代码:
class TrelloCycleTime
{
private $historyCards;
public function __construct()
{
$this->historyCards = [];
}
public function getAll()
{
$params = 'get params from other parts';
$this->historyCards = new HistoryCards($params);
}
}
一种方法是创建方法setHistoryCards
并传递模拟的historyCards
,但我不太喜欢。
另一种可能是拥有工厂。
有什么建议吗?
答案 0 :(得分:0)
一个明显的答案就是“使用工厂”。像这样(不好意思,我不是PHP程序员...):
class TrelloCycleTime
{
private $factory;
private $historyCards;
public function __construct($factory)
{
$this->factory = $factory;
}
public function getAll()
{
$params = 'get params from other parts';
$this->historyCards = $this->factory->construct($params);
}
}
在生产代码中,factory->construct()
返回一个实际的HistoryCards
对象,但是在单元测试中,您可以使其返回一个可以执行您喜欢的操作的模拟。
答案 1 :(得分:0)
您已经提到了二传手和工厂方法。下面我尝试解释另一种-但是请注意,我对PHP的使用经验为零,因此可能需要进行调整。而且,我并不是说这种方法比使用工厂更好-它只是根据您的特定情况可能有用的另一种选择。
在您的课程中,您不会直接访问historyCards
,而是在内部使用getter方法。在测试您的类时,您可以创建一个派生类,该派生类将覆盖getter,以不返回原始的historyCards
,而是返回模拟:
class TrelloCycleTime
{
private $historyCards;
public function __construct()
{
$this->historyCards = [];
}
protected function getHistoryCards()
{
return $this->historyCards;
}
public function soSomethingWithHistoryCards()
{
... do some computations, but don't ever use $this-> historyCards,
... but always fetch it via $this->getHistoryCards();
}
}
然后,在测试中,您可以使用以下派生类来测试类TrelloCycleTime
的方法。
class TrelloCycleTimeWithMockedHistoryCards extends TrelloCycleTime
{
public mockedHistoryCards; // public so you can access it easily from your tests.
public function __construct($mockedHistoryCards)
{
$this->historyCards = $mockedHistoryCards;
}
protected function getHistoryCards()
{
return $this->mockedHistoryCards;
}
}