我有一个构建在另一个框架之上的应用程序。所述框架具有许多值对象,我需要使用装饰器模式以各种方式扩展它们。让我们调用基础对象实体和装饰器类Wrappers。同一类的实体可以具有不同的“类型”,并且每种类型都需要不同的Wrapper类来公开特定于该类型的功能。此应用程序不是最后一层,不控制存在哪些类型或使用哪些类(在链的上方完成),因此赋值需要是动态的。
我创建了一个工厂类,它接收一个实体并为它确定正确的包装器。可以为工厂分配一个Wrapper类,以便在实体具有给定类型时使用。
<?php
class WrapperFactory
{
protected $default_wrapper = null;
protected $typed_wrappers = [];
public function __construct($default){
$this->setDefaultWrapper($default);
}
public function setDefaultWrapper($class){
if ($this->validateWrapperClass($class)){
$default_wrapper = $class;
}
}
public function getDefaultWrapper(){
return $this->$default_wrapper;
}
public function setWrapperForType($class, $type){
if($this->validateWrapperClass($class)){
$this->$typed_wrappers[$type] = $class;
}
}
public function hasWrapperForType($type){
return array_key_exists($type, $this->typed_wrappers);
}
public function getWrapperForType($type){
if($this->hasWrapperForType($type)){
return $this->typed_wrappers[$type];
}
else{
return $this->getDefaultWrapper();
}
}
public function wrap($entity)
{
$class = $this->getWrapperForType($entity->type);
return new $class($entity);
}
protected function validateWrapperClass($class){
if(class_exists($class) && class_implements($class, WrapperInterface::class)){
return true;
}else{
throw new BadMethodCallException("Wrapper must implement ". WrapperInterface::class . ".");
}
}
}
我不完全确定如何正确地对这个班级进行单元测试。有没有办法可以模拟实现接口的类而不是对象?如何测试分配给类型的类是否正常工作?我是否需要在我的测试文件中显式声明一个或两个虚拟类,或者有办法模拟它们吗?
答案 0 :(得分:0)
如果您创建一个Mock对象,PHPUnit将创建一个扩展您为其创建的类的类。因为这也适用于接口,所以您只需创建一个接口模拟并获取其类名:
$mock = $this->getMock('WrapperInterface');
$class = get_class($mock);
$this->assertTrue($factory->validateWrapperClass($class));