iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 11
0
自我挑戰組

單元測試開發購物車功能系列 第 12

Day12: 利用 Mockery spy 重構購物車的測試

  • 分享至 

  • xImage
  •  

昨天利用 Mockery 重構了 Cart Test 但看起來有點怪怪的
所以今天改用 spy 的方式來進行測試,
讓大家來比較一下這兩個測試方法的差異

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,
        ]);
    }
}

mock


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 的一些基本用法


上一篇
Day11: 使用 Mockery 重構 Cart 測試
系列文
單元測試開發購物車功能12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言