読者です 読者をやめる 読者になる 読者になる

はむはむエンジニアぶろぐ

このブログのコンセプトは"ハッキングの為なら愛する家族を傷つけることをいとわない" 自分にとってエンジニアリングは "手段ではなく生きる目的" である

PHP privateメソッドのテストをする

f:id:secret_hamuhamu:20150404170600p:plain
privateメソッドのテストどうするか議論ってテスト書いてる人なら必ずしたことありますよね?
私は、privateメソッドは、実装が隠されているのでprivateメソッドを呼び出しているpublicなメソッドさえテストすればいいと思っています。
privateメソッドの振る舞いをテストしたくなったら別のクラスに分けるべきではないかなと思います。

そんな、理論を持っている私ですが、あえてprivateメソッドのテストをします。
例えば、ビジネス的な制約で1週間後にprivateメソッド(手続き)のセマンティクスが変わるとかきっちり整理しにくい時もあると思います。
後々の拡張性と保守性が担保されていればいいと思うので、そういう時はprivateメソッドのテストを書いたりします。

環境構成

テストを書いてみる

実装コード オラオラ言うだけのメソッドを持つクラス。

<?php

class Hoge
{
    protected function oraOra()
    {
        echo 'オラオラオラオラ!';
    }
}

privateメソッド と言いましたが protectedメソッド にします。
protectedメソッドでもカプセル化されるので良いと思います。
継承して使われたくないメソッドは、 privateメソッド にしますが、そんなことは滅多にない。


テストコード テストコードの中に、先ほどの Hoge クラスを継承させた ExtHoge クラスを用意します。
ExtHogeクラスで、protectedメソッドをラップしたメソッドを用意してあげると HogeTest クラスで呼び出すことが可能です。

<?php
require_once 'Hoge.php';

class HogeTest extends PHPUnit_Framework_TestCase
{
    /**
     * @test
     */
    public function テスト()
    {
        $extHoge = new ExtHoge();

        $extHoge->publicOraOra();
    }
}

class ExtHoge extends Hoge
{
    public function publicOraOra()
    {
        $this->oraOra();
    }

}

まとめ

継承をすることでカプセル化されたメソッドをテストすることが出来る。
privateメソッドとかカプセル化されたメソッドをテストしたいときは、引っ掛かりがあるのでクラス設計を考えなおすとかも選択肢に入れるのが良いかと思います。


最近読んだ本

パーフェクトPHP

パーフェクトPHP

PHP Hacks ―プロが教えるWebプログラミングテクニック

PHP Hacks ―プロが教えるWebプログラミングテクニック

Laravelエキスパート養成読本 [モダンな開発を実現するPHPフレームワーク!]

Laravelエキスパート養成読本 [モダンな開発を実現するPHPフレームワーク!]