上下文:
我有这个接口扩展了其他三个接口:
interface BasicTagsInterface extends TitleTagInterface, DescriptionTagInterface, KeywordsTagInterface {}
TitleTagInterface
只有getSeoTitle
方法。DescriptionTagInterface
只有getSeoDescription
方法。KeywordsTagInterface
只有getSeoKeywords
方法。这是我想用PhpUnit测试的方法:
public function fromResource($resource)
{
if ($resource instanceof TitleTagInterface) {
$this->setTitle($resource->getSeoTitle());
}
if ($resource instanceof DescriptionTagInterface) {
$this->setDescription($resource->getSeoDescription());
}
if ($resource instanceof KeywordsTagInterface) {
$this->setKeywords($resource->getSeoKeywords());
}
}
这就是我到目前为止测试它的方式:
$resource = $this->getMockBuilder(BasicTagsInterface::class)->setMethods([
'getSeoTitle',
'getSeoDescription',
'getSeoKeywords',
])->getMock();
$resource->method('getSeoTitle')->willReturn('Awesome site');
$resource->method('getSeoDescription')->willReturn('My awesome site is so cool!');
$resource->method('getSeoKeywords')->willReturn('awesome, cool');
// TagBuilder::fromResource() is the method above
$this->tagBuilder->fromResource($resource);
我也尝试过:
class A implements BasicTagsInterface {
public function getSeoDescription(){}
public function getSeoKeywords(){}
public function getSeoTitle(){}
}
// And in the test method:
$resource = $this->getMockBuilder(A::class) // etc.
问题:
使用此配置,$resource instanseof BasicTagsInterface
返回true
,其他instanceof
测试返回false
。
我的问题:
我如何模拟扩展其他接口并在扩展接口上获得instanceof
测试的接口返回true,因为它们应该在测试用例之外?
答案 0 :(得分:2)
我在测试中找不到任何断言,但对我来说一切正常:
interface Title { function getTitle(); }
interface Description { function getDescription(); }
interface Resource extends Description, Title {}
class MyObject {
public $title;
public $description;
function fromResource(Resource $resource) {
if ($resource instanceof Title) {
$this->setTitle($resource->getTitle());
}
if ($resource instanceof Description) {
$this->setDescription($resource->getDescription());
}
}
function setTitle($title) { $this->title = $title; }
function setDescription($description) { $this->description = $description; }
}
class Question43426479Test extends TestCase {
function testFromResource() {
$resourceMock = $this->getMockBuilder(Resource::class)->getMock();
$resourceMock->method('getTitle')->willReturn('SomeTitle');
$resourceMock->method('getDescription')->willReturn('SomeDescription');
$object = new MyObject();
$object->fromResource($resourceMock);
$this->assertEquals('SomeTitle', $object->title);
$this->assertEquals('SomeDescription', $object->description);
}
}
当我运行测试时,我得到以下输出:
. 1 / 1 (100%)
Time: 66 ms, Memory: 8.00MB
OK (1 test, 2 assertions)
正如您所看到的,我的测试有两个断言。我不测试接口类型,因为我正在传递一个虚拟对象,我不关心它的接口,但它是否在传递给我的Object-class'fromResource方法时产生了正确的结果。相反,我主张该类中的预期结果,即是否调用了setter。
如果您想测试您的资源是否属于特定类型,我会创建一个实现该接口的类:
class MyResource implements Resource
{
...
}
然后编写一个单独的测试,确保在构造MyResource时它是所需接口的实例:
function testResourceImplementsTitleAndDescription()
{
$resource = new MyResource();
$this->assertInstanceOf(Title::class, $resource);
$this->assertInstanceOf(Description::class, $resource);
}
正如你所看到的,我在这里不使用模拟,因为我想知道实际的对象而不是在它的位置创建的虚拟对象。