首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >PHPUnit TDD问题

PHPUnit TDD问题
EN

Stack Overflow用户
提问于 2015-01-31 22:38:04
回答 1查看 74关注 0票数 2

我在学习TDD,我有一些问题。-这个想法是在测试的指导下建立一个简单的工厂。问题是,我的考试覆盖率不是100%,这就是我的问题所在。

在我给你看密码之前,让我解释一下我想要什么。

  • 工厂响应于实例化类,为了测试这个类,我必须模拟类的实例化--我使用的是一个具体的类,它可以工作,但是当我看到测试覆盖率时,出现了具体的类,而且它没有100%测试。(你会明白的)。-我想避免这种情况,我想尽可能抽象地测试工厂。
  • 另一个问题是,我想将工厂作为对构造函数的依赖项插入,如何测试它?

覆盖范围:

  • PizzaStore.php -33%-工厂依赖的构造函数没有测试。
  • PizzaFactory.php - 100%
  • Pizza.php - 100%
  • 比萨饼/Greek.php- 0.00% -是在使用混凝土类测试工厂之后出现的。

PizzaTest.php:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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');
  }

}

就这样,有什么不对的,请说出来。提前谢谢你。

EN

回答 1

Stack Overflow用户

发布于 2015-02-01 10:47:10

工厂负责实例化类,为了测试这个类,我必须模拟类的实例化--我使用的是一个具体的类,它可以工作,但是当我看到测试覆盖率时,出现了具体的类,而且它没有100%测试。(你会明白的)。-我想避免这种情况,我想尽可能抽象地测试工厂。

PizzaStore类的这种缺失是因为当工厂找不到类时没有测试用例。

缺少测试用例:

代码语言:javascript
复制
/**
 * @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模拟是如何工作的,但是在乌萨饼模拟实用程序中,这看起来是这样的:

代码语言:javascript
复制
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是否被调用。

此外,在我看来,在您的情况下,最好使用接口大于继承

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28257338

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档