我在学习TDD,我有一些问题。-这个想法是在测试的指导下建立一个简单的工厂。问题是,我的考试覆盖率不是100%,这就是我的问题所在。
在我给你看密码之前,让我解释一下我想要什么。
覆盖范围:

PizzaTest.php:
<?php namespace Pattern\SimpleFactory;
use PHPUnit_Framework_TestCase;
class PizzaTest extends PHPUnit_Framework_TestCase {
private $pizza;
public function setUp()
{
$this->pizza = $this->getMockForAbstractClass('Pattern\SimpleFactory\Pizza');
}
/**
* @covers Pattern\SimpleFactory\Pizza::setName
* @covers Pattern\SimpleFactory\Pizza::getName
*/
public function testPizzaSetsAndReturnsTheExpectedName()
{
$pizzaName = 'Greek Pizza';
$this->pizza->setName($pizzaName);
$this->assertEquals($pizzaName, $this->pizza->getName());
}
/**
* @covers Pattern\SimpleFactory\Pizza::setDescription
* @covers Pattern\SimpleFactory\Pizza::getDescription
*/
public function testPizzaSetsAndReturnsTheExpectedDescription()
{
$pizzaDescription = 'A Pepperoni-style pizza with dough, tomato, and cheese';
$this->pizza->setDescription($pizzaDescription);
$this->assertEquals($pizzaDescription, $this->pizza->getDescription());
}
}PizzaStoreTest.php:
<?php namespace Pattern\SimpleFactory;
use PHPUnit_Framework_TestCase;
class PizzaStoreTest extends PHPUnit_Framework_TestCase {
/**
* @covers Pattern\SimpleFactory\PizzaStore::order
*/
public function testStoreShouldReturnsTheRequestedPizzaWhenOrdered()
{
$factory = new PizzaFactory();
$store = new PizzaStore($factory);
$pizza = $store->order('greek');
$this->assertInstanceOf('Pattern\SimpleFactory\Pizza', $pizza);
}
}PizzaFactoryTest.php:
<?php namespace Pattern\SimpleFactory;
use PHPUnit_Framework_TestCase;
class PizzaFactoryTest extends PHPUnit_Framework_TestCase {
/**
* @var PizzaFactory
*/
private $pizzaFactory;
public function setUp()
{
$this->pizzaFactory = new PizzaFactory();
}
/**
* @covers Pattern\SimpleFactory\PizzaFactory::make
*/
public function testPizzaFactoryMakesAPizza()
{
$pizza = $this->pizzaFactory->make('greek');
$this->assertInstanceOf('Pattern\SimpleFactory\Pizza', $pizza);
}
/**
* @covers Pattern\SimpleFactory\PizzaFactory::make
*/
public function testPizzaFactoryReturnsNullWhenMakingANonexistentPizza()
{
$pizza = $this->pizzaFactory->make(null);
$this->isNull($pizza);
}
}PizzaStore.php:
<?php namespace Pattern\SimpleFactory;
/**
* @package Pattern\SimpleFactory
*/
class PizzaStore {
/**
* @var PizzaFactory
*/
private $factory;
/**
* @param PizzaFactory $factory
*/
function __construct(PizzaFactory $factory)
{
$this->factory = $factory;
}
/**
* @param string $name
* @return null|Pizza
*/
public function order($name)
{
return $this->factory->make($name);
}
}PizzaFactory.php:
<?php namespace Pattern\SimpleFactory;
/**
* @package Pattern\SimpleFactory
*/
class PizzaFactory {
/**
* @var array
*/
private $pizzas = [
'greek' => 'Pattern\SimpleFactory\Pizza\Greek',
'pepperoni' => 'Pattern\SimpleFactory\Pizza\Pepperoni',
];
/**
* @param string $name
* @return null|Pizza
*/
public function make($name)
{
if (isset($this->pizzas[$name]))
{
return new $this->pizzas[$name];
}
return null;
}
}Pizza.php:
<?php namespace Pattern\SimpleFactory;
/**
* @package Pattern\SimpleFactory
*/
abstract class Pizza {
/**
* @var string
*/
private $name;
/**
* @var string
*/
private $description;
/**
* @return string
*/
public function getName()
{
return $this->name;
}
/**
* @param string $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* @return string
*/
public function getDescription()
{
return $this->description;
}
/**
* @param string $description
*/
public function setDescription($description)
{
$this->description = $description;
}
}Pizza\Pepperoni.php:
<?php namespace Pattern\SimpleFactory\Pizza;
use Pattern\SimpleFactory\Pizza;
/**
* @package Pattern\SimpleFactory\Pizza
*/
class Pepperoni extends Pizza {
function __construct()
{
parent::setName('Pizza Pepperoni');
parent::setDescription('A Pepperoni-style pizza with dough, tomato, and cheese');
}
}Pizza\Greek.php:
<?php namespace Pattern\SimpleFactory\Pizza;
use Pattern\SimpleFactory\Pizza;
/**
* @package Pattern\SimpleFactory\Pizza
*/
class Greek extends Pizza {
function __construct()
{
parent::setName('Pizza Greek');
parent::setDescription('A Greek-style pizza with feta cheese, onion, olive and tomato');
}
}就这样,有什么不对的,请说出来。提前谢谢你。
发布于 2015-02-01 10:47:10
工厂负责实例化类,为了测试这个类,我必须模拟类的实例化--我使用的是一个具体的类,它可以工作,但是当我看到测试覆盖率时,出现了具体的类,而且它没有100%测试。(你会明白的)。-我想避免这种情况,我想尽可能抽象地测试工厂。
PizzaStore类的这种缺失是因为当工厂找不到类时没有测试用例。
缺少测试用例:
/**
* @covers Pattern\SimpleFactory\PizzaStore::order
*/
public function testStoreShouldReturnsTheRequestedPizzaWhenOrdered()
{
$factory = new PizzaFactory();
$store = new PizzaStore($factory);
$pizza = $store->order('not exists pizza type');
$this->assertNull($pizza);
}另一个问题是,我想将工厂作为对构造函数的依赖项插入,如何测试它?
您可以使用模拟的PizzaFactory类,然后调用验证。我不知道PHPUnit模拟是如何工作的,但是在乌萨饼模拟实用程序中,这看起来是这样的:
public function testFactory()
{
$factory = Mock::create('\Pattern\SimpleFactory\PizzaFactory');
Mock::when($factory)->make()->thenReturn(new \Pattern\SimpleFactory\Pizza\Greek());
$magic = new Magic($factory);
$order = $magic->order();
Mock::verify($factory)->make();
$this->assertInstanceOf('\Pattern\SimpleFactory\Pizza\Greek', $order);
}此Mock::verify方法检查方法PizzaFactory::make是否被调用。
此外,在我看来,在您的情况下,最好使用接口大于继承。
https://stackoverflow.com/questions/28257338
复制相似问题