PHPUnit3で始めるユニットテスト

第3回 ショッピングカートクラスを作ってみる(2)

この記事を読むのに必要な時間:およそ 18 分

5番目の仕様「すべての商品コードと数量をまとめて取得できる」

1番目の仕様を実装する際に追加したgetItemsメソッドですが,テストをまだ追加していませんでしたので,テストを追加しておきましょう。ここでは,以下の2つのテストを考えてみました。

  • カートに複数の商品を追加した場合の商品種の数
  • getItemsメソッドで取得したハッシュの内容のチェック

テストを追加したテストケースは次のようになりました。

<?php
require_once 'PHPUnit/Framework.php';
require_once 'Cart.php';

class CartTest extends PHPUnit_Framework_TestCase
{
    public function testInitCart() {
        $cart = new Cart();
        $this->assertTrue(is_array($cart->getItems()));
        $this->assertEquals(0, count($cart->getItems()));
    }

    public function testAdd() {
        $cart = new Cart();
        $this->assertTrue($cart->add('001', 1));
        $this->assertTrue($cart->add('001', 0));
        $this->assertTrue($cart->add('001', -1));
    }

    public function testAddNotNumeric() {
        $cart = new Cart();
        try {
            $cart->add('001', 'string');
        } catch (UnexpectedValueException $e) {
            return;
        }
        $this->fail();
    }

    public function testAddFloat() {
        $cart = new Cart();
        try {
            $cart->add('001', 1.5);
        } catch (UnexpectedValueException $e) {
            return;
        }
        $this->fail();
    }

    public function testGetAmount() {
        $cart = new Cart();
        $this->assertEquals(0, $cart->getAmount('001'));
        $cart->add('001', 1);
        $this->assertEquals(1, $cart->getAmount('001'));

        $this->assertEquals(0, $cart->getAmount('999'));

        $cart->add('002', 1);
        $this->assertEquals(1, $cart->getAmount('001'));
        $this->assertEquals(1, $cart->getAmount('002'));

        $cart->add('001', -1);
        $this->assertEquals(0, $cart->getAmount('001'));
        $this->assertEquals(1, $cart->getAmount('002'));
    }

    public function testGetItems() {
        $cart = new Cart();
        $cart->add('001', 3);
        $this->assertEquals(1, count($cart->getItems()));
        $cart->add('002', 2);
        $this->assertEquals(2, count($cart->getItems()));

        $items = $cart->getItems();
        $this->assertEquals(3, $items['001']);
        $this->assertEquals(2, $items['002']);
    }
}
$ phpunit CartTest
PHPUnit 3.1.7 by Sebastian Bergmann.

.....F

Time: 0 seconds

There was 1 failure:

1) testGetItems(CartTest)
Failed asserting that <integer:0> matches expected value <integer:1>.
/home/shimooka/public_html/gihyo.jp/CartTest.php:60

FAILURES!
Tests: 6, Failures: 1.
$ 

おっと。getItemsメソッドは,1つ目の仕様を実装した際の仮実装のままでした。ここで,Cartクラスを修正して再度テストします。

<?php
class Cart
{
    private $items;

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

    public function getItems() {
        return $this->items;
    }

    public function add($item_cd, $amount) {
        if (preg_match('/^-?\d+$/', $amount)) {
            if (!isset($this->items[$item_cd])) {
                $this->items[$item_cd] = 0;
            }
            $this->items[$item_cd] += (int)$amount;
            return true;
        } else {
            throw new UnexpectedValueException('Invalid amount');
        }
    }

    public function getAmount($item_cd) {
        if (isset($this->items[$item_cd])) {
            return $this->items[$item_cd];
        } else {
            return 0;
        }
    }
}
$ phpunit CartTest
PHPUnit 3.1.7 by Sebastian Bergmann.

......

Time: 0 seconds


OK (6 tests)
$ 

著者プロフィール

下岡秀幸(しもおかひでゆき)

PHP関連の情報サイト「Do You PHP?」の管理人。PHP歴は長いが,あまり仕事で使ったことがないという噂がある。最近はα版のPEAR・PECLに手を出しては地雷を踏んでいることが多い。

URLhttp://www.doyouphp.jp/http://d.hatena.ne.jp/shimooka/