3

私の静的メソッドは、「ヘルパー」の種類(例convertToCamelCase())または「シングルトンの取得」の種類(例:)のいずれかですgetInstance()。いずれにせよ、私は彼らがヘルパークラスに住んでいることを嬉しく思います。

ヘルパークラスは広く利用可能である必要があるため、レイヤースーパータイプにロードしています。今、私が見る限り、ヘルパーをスーパータイプに注入できるという条件で、コードのテストに対して完全な柔軟性を維持しています(ヘルパークラス自体を除く)。それは理にかなっていますか?それとも私は何かを見落としていますか?

別の見方をすると...コードのテストの難しさは、静的メソッド自体の実際の数ではなく、静的メソッドの呼び出しの数に比例して増加するように思われます。これらすべての呼び出しを1つのクラス(私のヘルパー)に入れ、そのクラスをモックに置き換えることで、静的呼び出しや関連する問題のないコードをテストしています。

(私は自分のシングルトンを取り除くことに向けて取り組むべきだと理解していますが、それはより長期的なプロジェクトになるでしょう)。

4

2 に答える 2

1

「convertToCamelCase」のような厳密にヘルパー関数である静的クラスの場合、おそらくその関数を100%カバーし、それを「コア」関数と見なし、他の場所でモックする心配はありません。とにかく「convertToCamelCase」のモックは何をするのか..?単体テストは、やりすぎると統合テストのような匂いがし始めますが、すべてを抽象化することとアプリを不必要に複雑にすることの間には、常に少しのトレードオフがあります。

シングルトンに関しては、通常、コードに静的クラスの名前が含まれているため、テストのためにモックオブジェクトと交換するのが問題になるため、注意が必要です。静的メソッド呼び出しを行う場所で実行できることの1つは、リファクタリングから始めて、次のように呼び出すことです。

$instance = call_user_func('MyClass::getinstance');

次に、テストカバレッジを増やすと、次のようなものに置き換え始めることができます。

$instance = call_user_func($this->myClassName . '::getinstance');

つまり、それができたら、をMyClass変更してスワップアウトしてモックすることができます$this->myClassName。関連するphpファイルも動的に要求または自動ロードしていることを確認する必要があります。

抽象ファクトリパターンを使用するようにリファクタリングすると、テストがさらに簡単になりますが、時間の経過とともに実装を開始することもできます。

于 2013-03-26T23:43:23.140 に答える
0

ただし、静的クラスをどこかでモックする必要がある場合は、Mokalibraryを使用してモックすることができます。次に例を示します。

class UsersController
{

    public function main()
    {
        return json_encode(User::find(1));
    }
}

これはあなたがそれをテストする方法です:

class UsersController
{
    private $_userClass;

    public function __construct($userClass = 'User')
    {
        $this->_userClass = $userClass;
    }

    public function find($id)
    {
        return json_encode($this->_userClass::find($id));
    }
}

class UsersControllerTest extends \PHPUnit_Framework_TestCase
{
    public function testMainReturnsUser()
    {
        $userClass = Moka::stubClass(null, ['::find' => 'USER']);
        $controller = new UsersController($userClass);
        $this->assertEquals('"USER"', $controller->find(1000));
    }

    public function testMainCallsFind()
    {
        $userClass = Moka::stubClass(null, ['::find' => 'USER']);
        $controller = new UsersController($userClass);
        $controller->find(1000);
        // check that `find` was called with 100
        $this->assertEquals([1000], $userClass::$moka->report('find')[0]);
    }
}
于 2016-07-10T03:39:07.323 に答える