在 PHP 中模拟不存在的界面
Mock Non-existent Interface in PHP
我是 PHP 单元测试的新手,我需要弄清楚我们如何模拟不存在的接口。基本上,在我的项目中,我想测试一个受保护的方法,它需要两个参数,一个是接口,另一个是字符串。
我想了解如何将接口作为参数传递给方法。我尝试模拟界面,但它对我不起作用。
这是我的主class
namespace App\Models;
class VerifyNs {
protected function NsCheck(SomeInterface $url, string $domain) {
$answer= dns_get_record($domain, DNS_NS);
if (!empty($answer[0]['target']), ('example.com' == substr($answer[0]['target'], -11)) {
$result = 'NS verification for @url passed., ['@url ' => $url ->getName()]';
return $result
}
return 'failed;
}
}
这里是测试用例
class VerifyNsTest extends \PHPUnit\Framework\TestCase
{
/**
* To call protected method
* @param $object
* @param string $method
* @param array $parameters
* @return mixed
* @throws \Exception
*/
private function callMethod($object, string $method , array $parameters = [])
{
try {
$className = get_class($object);
$reflection = new \ReflectionClass($className);
} catch (\ReflectionException $e) {
throw new \Exception($e->getMessage());
}
$method = $reflection->getMethod($method);
$method->setAccessible(true);
return $method->invokeArgs($object, $parameters);
}
/**
* Tests for verifying NS of the domain.
*
* @dataProvider providerTestNsCheck
*/
public function testCheckNs($site, $url, $expected_result) {
$site_name = $this->getMockBuilder(SomeInterface::class)
->setMethods(['getName'])
->getMock();
$site_name->method('getName')->willReturn($site);
$verifyNs = new \App\Models\VerifyNs();
$this->assertEquals($expected_result, $this->callMethod($verifyNs, 'NsCheck', [ $site_name, $url]));
}
/**
* Data provider for testCheckNs().
*
*/
public function providerTestNsCheck() {
return [
[
'mysite',
'example.com',
'NS verification for mysite passed.',
], [
'google',
'google.com',
'failed.'
]
],
];
}
}
在 运行 之后,它给我一个错误
TypeError: Argument 1 passed to App\Models\VerifyNs::NsCheck() must be an instance of App\Models\SomeInterface, instance of Mock_SomeInterface_1ee04960 given
有人可以帮忙吗?是否可以模拟 non_existent 接口并将其作为参数传递给方法?
我能够使用 prophesize
解决这个问题
$site = $this->prophesize(SomeInterface::class);
$object =$site->reveal()
然后在 callMethod 中传递 $object。
我是 PHP 单元测试的新手,我需要弄清楚我们如何模拟不存在的接口。基本上,在我的项目中,我想测试一个受保护的方法,它需要两个参数,一个是接口,另一个是字符串。
我想了解如何将接口作为参数传递给方法。我尝试模拟界面,但它对我不起作用。
这是我的主class
namespace App\Models;
class VerifyNs {
protected function NsCheck(SomeInterface $url, string $domain) {
$answer= dns_get_record($domain, DNS_NS);
if (!empty($answer[0]['target']), ('example.com' == substr($answer[0]['target'], -11)) {
$result = 'NS verification for @url passed., ['@url ' => $url ->getName()]';
return $result
}
return 'failed;
}
}
这里是测试用例
class VerifyNsTest extends \PHPUnit\Framework\TestCase
{
/**
* To call protected method
* @param $object
* @param string $method
* @param array $parameters
* @return mixed
* @throws \Exception
*/
private function callMethod($object, string $method , array $parameters = [])
{
try {
$className = get_class($object);
$reflection = new \ReflectionClass($className);
} catch (\ReflectionException $e) {
throw new \Exception($e->getMessage());
}
$method = $reflection->getMethod($method);
$method->setAccessible(true);
return $method->invokeArgs($object, $parameters);
}
/**
* Tests for verifying NS of the domain.
*
* @dataProvider providerTestNsCheck
*/
public function testCheckNs($site, $url, $expected_result) {
$site_name = $this->getMockBuilder(SomeInterface::class)
->setMethods(['getName'])
->getMock();
$site_name->method('getName')->willReturn($site);
$verifyNs = new \App\Models\VerifyNs();
$this->assertEquals($expected_result, $this->callMethod($verifyNs, 'NsCheck', [ $site_name, $url]));
}
/**
* Data provider for testCheckNs().
*
*/
public function providerTestNsCheck() {
return [
[
'mysite',
'example.com',
'NS verification for mysite passed.',
], [
'google',
'google.com',
'failed.'
]
],
];
}
}
在 运行 之后,它给我一个错误
TypeError: Argument 1 passed to App\Models\VerifyNs::NsCheck() must be an instance of App\Models\SomeInterface, instance of Mock_SomeInterface_1ee04960 given
有人可以帮忙吗?是否可以模拟 non_existent 接口并将其作为参数传递给方法?
我能够使用 prophesize
解决这个问题$site = $this->prophesize(SomeInterface::class); $object =$site->reveal()
然后在 callMethod 中传递 $object。