[英]Error mocking concrete class with PHP mockery
The class under test is as follows: 被测类如下:
class ElasticSearchInstaller
{
/**
* Version of ElasticSearch
*
* @var \ElasticSearch\Requierments
*/
protected $requirements;
/**
* Object Constructor.
*
* @param Requierments $requirements
*/
public function __construct(Requirements $requirements)
{
$this->requirements = $requirements;
}
/**
* Set requirements
*
* @return bool
*/
public function canInstall()
{
return ($this->isInstalled() && $this->requirements->checkRequirements());
}
}
The test looks as follows: 该测试如下所示:
class ElasticSearchInstallerTest extends TestCase
{
/** @test **/
public function it_can_check_if_its_installable()
{
$requirements = m::mock('alias:ElasticSearch\Requirements');
$requirements->shouldReceive('checkRequirements')->once()->andReturn(true);
$installer = new ElasticSearchInstaller($requirements);
$this->assertInternalType('bool', $installer->canInstall());
}
}
Although for some reason it does not pass, as the mock says checkRequirements()
is not being called and expects to be called once. 尽管由于某种原因它没有通过,但正如模拟所说的那样,
checkRequirements()
没有被调用,并且期望被调用一次。
1) ElasticSearchInstallerTest::it_can_check_if_its_installable
Mockery\Exception\InvalidCountException: Method checkRequirements() from App\ElasticSearch\Requirements should be called
exactly 1 times but called 0 times.
EDIT The problem was, within canInstall()
for some reason if $this->isInstalled()
is called before $this->requirements->checkRequirements()
such as in the code above. 编辑的问题是,内
canInstall()
由于某种原因,如果$this->isInstalled()
之前被调用$this->requirements->checkRequirements()
如在上面的代码。 It errors. 错误。 if its swapped to:
如果将其交换为:
public function canInstall()
{
return ($this->requirements->checkRequirements() && $this->isInstalled() );
}
...it passes! ...它过去了! wtf?
wtf?
The issue is that such boolean conditions can be shortcut -if the first part of an &&
(and) condition is FALSE, the whoe condition itself cannot become true, and so the rest of the parts of the conditional is skipped. 问题是这种布尔条件可以是快捷方式-如果
&&
(and)条件的第一部分为FALSE,则whoe条件本身无法变为真,因此该条件的其余部分将被跳过。 The function call was skipped, hence, run 0 times. 该函数调用被跳过,因此运行0次。
Since, in that specific test, you only only currently testing the condition as a whole, you can mock the rest of the ElasticSearchInstaller
and do much the same: 由于在该特定测试中,您仅当前仅对整个条件进行了测试,因此您可以模拟其余的
ElasticSearchInstaller
并执行相同的操作:
$searchInstaller->shouldReceive('isInstalled')->andReturn(true);
The mock would fall back to use the original canInstall(), and so run the condition. 该模拟将回退以使用原始的canInstall(),然后运行该条件。 It's still almost a too-simple-to-fail case though - I'd concentrate elsewhere for testing.
但是,这仍然几乎是一个太简单到无法通过的案例-我将精力集中在其他地方进行测试。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.