4

次のメソッドを使用して、シングルトン クラスの動作をテストしたいと考えています。

public class SomeSingleton
{
    private final static int DEFAULT_VALUE1 = ...;
    private final static int DEFAULT_VALUE2 = ...;

    private static SomeSingleton instance;

    public static void init(int value1, int value2)
    {
        if (instance != null)
        {
            throw new IllegalStateException("SomeSingleton already initialized");
        }

        instance = new SomeSingleton(value1, value2);
    }

    public static getInstance()
    {
        if (instance == null)
        {
            init(DEFAULT_VALUE1, DEFAULT_VALUE2);
        }

        return instance;
    }
}

initそして、複数回呼び出すいくつかのテスト メソッドを持つテスト クラスがあります。

@RunWith(PowerMockRunner.class)
@PrepareForTest(SomeSingleton.class)
public class SomeSingletonTest {
    @Test
    public void testGetInstanceSunnyDay()
    {
        [...]
        SomeSingleton.init(...);
        [...]
        SomeSingleton.getInstance();
        [...]
    }

    @Test
    public void testGetInstanceRainyDay()
    {
        [...]
        SomeSingleton.init(...); // IllegalStateException
        [...]
        SomeSingleton.getInstance();
        [...]
    }
}

このようにするとIllegalStateExceptioninstance != null.

init1 つのテスト クラスに関連する複数のテストを実行するにはどうすればよいですか?

testGetInstanceSunnyDayとを 2 つの別々testGetInstanceRainyDayのクラスに入れることで問題は解決しますが、より良い解決策があるかどうか疑問に思っています。

4

3 に答える 3

5

基本的に、シングルトンはテストが困難です。まさにこの種のことからです。メソッドを追加できますclearStateForTesting

static void clearStateForTesting() {
    instance = null;
}

...しかし、可能であれば、最初からシングルトン パターンを避けることをお勧めします。

また、シングルトンの実装は現時点ではスレッドセーフではないことに注意してください。本当にシングルトンを使用する必要がある場合は、大幅に優れた実装があります。

于 2013-09-20T13:21:20.187 に答える
0

シングルトンであることを考えると、このinitメソッドはパブリック メソッドとしては意味がありません。それを作成して、単体テストでprivateのみ使用してください。getInstance

于 2013-09-20T19:21:32.257 に答える