Lzh on GitHub

简单示例

假设我们有一个 Temperature 类,它在报告平均温度之前对某个地区进行温度采样。数据可以来自 Web 服务或任何其他数据源,但我们目前没有这样的类。但是,我们可以根据它与 Temperature 类的交互,假设此类的一些基本交互:

假设我们有一个 Temperature 类,它在报告平均温度之前对某个地区进行温度采样。数据可以来自 Web 服务或任何其他数据源,但我们目前没有这样的类。但是,我们可以根据它与 Temperature 类的交互,假设此类的一些基本交互:

class Temperature
{
    private $service;

    public function __construct($service)
    {
        $this->service = $service;
    }

    public function average()
    {
        $total = 0;
        for ($i = 0; $i < 3; $i++) {
            $total += $this->service->readTemp();
        }
        return $total / 3;
    }
}

即使没有实际的服务类,我们也可以看到我们期望它如何操作。在为 Temperature 类编写测试时,我们现在可以用一个模拟对象代替真实服务,这使我们能够在不需要具体服务实例的情况下测试 Temperature 类的行为。

use \Mockery;

class TemperatureTest extends \PHPUnit\Framework\TestCase
{
    public function tearDown()
    {
        Mockery::close();
    }

    public function testGetsAverageTemperatureFromThreeServiceReadings()
    {
        $service = Mockery::mock('service');
        $service->shouldReceive('readTemp')
            ->times(3)
            ->andReturn(10, 12, 14);

        $temperature = new Temperature($service);

        $this->assertEquals(12, $temperature->average());
    }
}

我们创建一个模拟对象,Temperature 类将使用它,并为该模拟对象设置一些期望——它应该接收三次对 readTemp 方法的调用,并且这些调用将返回 10、12 和 14 作为结果。

PHPUnit 集成可以消除对 tearDown() 方法的需要。有关更多信息,请参阅 PHPUnit 集成