昨天利用 Mockery 重構了 Cart Test 但看起來有點怪怪的
所以今天改用 spy 的方式來進行測試,
讓大家來比較一下這兩個測試方法的差異
namespace Recca0120\Cart\Tests;
use Mockery as m;
use Recca0120\Cart\Cart;
use Recca0120\Cart\Item;
use Recca0120\Cart\Store;
use PHPUnit\Framework\TestCase;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
class CartTest extends TestCase
{
use MockeryPHPUnitIntegration;
/** @test */
public function 將商品加入購物車並驗證商品有名稱單價數量()
{
$item = $this->createItem('商品01', 100, 1);
$store = m::spy(Store::class);
$cart = new Cart($store);
$cart->put($item);
$store->shouldHaveReceived('put')->with($item)->once();
}
/** @test */
public function 加總()
{
$store = m::mock(Store::class);
$store->shouldReceive('items')->once()->andReturnUsing(function () {
return [
$this->createItem('商品01', 100, 2),
$this->createItem('商品02', 200, 1),
];
});
$cart = new Cart($store);
$this->assertEquals(400, $cart->total());
}
/** @test */
public function 移除商品()
{
$item = $this->createItem('商品01', 100, 2);
$store = m::spy(Store::class);
$cart = new Cart($store);
$cart->remove($item);
$store->shouldHaveReceived('remove')->once()->with($item);
}
private function createItem($name, $price, $qty)
{
return new Item([
'name' => $name,
'price' => $price,
'quantity' => $qty,
]);
}
}
namespace Recca0120\Cart\Tests;
use Mockery as m;
use Recca0120\Cart\Cart;
use Recca0120\Cart\Item;
use Recca0120\Cart\Store;
use PHPUnit\Framework\TestCase;
use Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration;
class CartTest extends TestCase
{
use MockeryPHPUnitIntegration;
/** @test */
public function 將商品加入購物車並驗證商品有名稱單價數量()
{
$item = $this->createItem('商品01', 100, 1);
$store = m::mock(Store::class);
$store->shouldReceive('put')->with($item)->once();
$cart = new Cart($store);
$cart->put($item);
}
/** @test */
public function 加總()
{
$store = m::mock(Store::class);
$store->shouldReceive('items')->once()->andReturnUsing(function () {
return [
$this->createItem('商品01', 100, 2),
$this->createItem('商品02', 200, 1),
];
});
$cart = new Cart($store);
$this->assertEquals(400, $cart->total());
}
/** @test */
public function 移除商品()
{
$item = $this->createItem('商品01', 100, 2);
$store = m::mock(Store::class);
$store->shouldReceive('remove')->once()->with($item);
$cart = new Cart($store);
$cart->remove($item);
}
private function createItem($name, $price, $qty)
{
return new Item([
'name' => $name,
'price' => $price,
'quantity' => $qty,
]);
}
}
改用 spy 是不是更清楚呢?
對 Mock Framework 不熟的人應該對這兩天的內容會有點混亂
所以明天還是來談談 Mockery 的一些基本用法