0

PHP プロジェクトには、メインのシングルトンと、メインのシングルトンを使用する他のシングルトンがあります。

<?php

class SingletonMain
{
    // Main singleton
    // ...
}

class SingletonA
{
    protected $main;

    function __construct()
    {
        $main = SingletonMain::getInstance();
    }
}

class SingletonB
{
    protected $main;

    function __construct()
    {
        $main = SingletonMain::getInstance();
    }
}
?>

SingletonASingletonBSingletonMainをモックする最も簡単な方法は、 SingletonMainインスタンスへの参照を取得してこれを実行することだと思いました。

  1. SingletonMainインスタンスを にコピーします$temp
  2. SingletonMainの代わりにMockSingletonMainインスタンスを配置します。「その場で」とは、同じ参照場所で、SingletonASingletonBが新しいモックを元のSingletonMainであるかのようにすぐに使用できることを意味します。
  3. テスト。
  4. SingletonMainインスタンスを元の場所に戻し$tempます。

それは可能ですか?そうでない場合、すべてのSingletonsABCDでSingletonMainをモックする最も簡単な方法は何ですか....

$this->main = $my_mock現在、私の唯一の解決策は、これらのリーフシングルトンのそれぞれに新しいモックを明示的に設定し、最後に通常の代入演算子を使用して(およびテスト後に)もう一度元に戻すこと$this->main = SingletonMain::getInstance()です。

編集

いくつかの回答を読んで、さらに情報を提供する必要があることに気付きました。私はこれらのリーフシングルトンを約20〜30個持っています。このアプリケーションは、そもそも数年前にテストするように設計されていなかったので、今は何も壊さず、できるだけ変更を加えずにシングルトン パターンを回避する最善の方法を探しています。

4

3 に答える 3

0

SingletonA はコード内のシングルトンではないため、モック化された SingletonMain インスタンスをテストで簡単に渡すことができます。

class SingletonA
{
    protected $main;

    function __construct($main = null)
    {
        if (!$main) $main = SingletonMain::getInstance();
        $this->main = $main;
    }
}

何も渡されない場合は、現在の動作に戻ります。

于 2012-10-10T19:36:33.170 に答える
0

テストスタブを作成することでそれを行うことができます:

class SingletonAStub extends SingletonA
{

    public function getMain() {
        return $this->main;
    }

    public function setMain($main) {
        $this->main = $main;
    }
}

テストではスタブを使用し、必要に応じて「シングルトン」を変更してテストします。

当然、直接シングルトンを使用しない方がはるかに優れているため、テストのためだけに特別なサブタイプを作成する必要はあまりありません。

于 2012-10-10T20:02:56.833 に答える
0

必要なのは継承のようです。このような:

class SingletonA extends SingletonMain {
    // Your code specific to SingletonA here.
}

class SingletonB extends SingletonMain {
    // Your code specific to SingletonB here.
}
于 2012-10-10T19:39:55.420 に答える