2017-04-18 14 views
1

私は既存のクラスのテストを書こうとしています。以下はモック内側の最終オブジェクト

class ClassToBeTested { 

    private final Obj1 a; 

    ClassToBeTested(String anotherVariable) { 

    a = new Obj1(anotherVariable); 
    } 

public void methodToBeTested() { 

    if(invokeSomeOtherMethod()) { 
      a.getAnotherVariable().doSomething(); 
    } 
} 

public boolean invokeSomeOtherMethod() { 
     // return true or false based on some logic 
} 

Obj1 getObj1() { 
    return a; 
} 

} 

私のテストクラスである:

class TestClass { 


    @Test 
    public void testMethod() { 

     ClassToBeTested x = new ClassToBeTested("someString"); 
     ClassToBeTested spyX = spy(x); 
     doReturn(false).when(spyX).invokeSomeOtherMethod(); 

     spyX.methodToBeTested(); 
     verify(spyX, times(1)).getObj1().doSomething(); 

    } 
} 

これが私の理解です: OBJ1は、クラスのコンストラクタで作成された民間最終的なオブジェクトであるので、それが直接試験方法でアクセスされないことがどちらもobj1の模擬バージョンを使用するようにspyObjectを強制することもできません。

また以来(検証)がOBJ1の嘲笑バージョンを必要とし、それは私にエラーがスローされます: Wanted But Not invoked: x.getObj1(), however there are otherInteractions with this mock: x.invokeSomeOtherMethod()

は間違って私の理解ですか? testMoethod()をテストする方法は何でしょうか?

+0

コンストラクタを変更して、 'a'を注入しますか? –

+0

プロジェクトの複数のファイルに変更を加える必要があるので、私はそれを避けたいと思います。また、 'anotherVariable'は現在使用されていない文字列であるため、aの初期化はそれを呼び出すコードに直接依存しません。 – learningMyWayThru

+1

あなたのコードを理解できません。クラスには1つのコンストラクタだけが表示されます。パラメータのないコンストラクタはありません。しかし、あなたはテストメソッドでパラメータなしのコンストラクタを使用しています。どちらが正しいですか? –

答えて

1

あなたは正しくする方法を理解していないようです依存性注入

class ClassToBeTested { 

    private final Obj1 a; 

    public ClassToBeTested(String anotherVariable) { 
    this(new Obj1(anotherVariable)); 
    } 

    ClassToBeTested(Obj1 a) { 
    this.a = a; 
    } 

完了:ちょうど例えばコンストラクタテレスコープを使用する - あなたはそれが簡単にテストできるようにするためにすべてのコードを変更する必要はありません。今すぐのインスタンスを挿入するために使用できるパッケージ保護されたコンストラクタがあります。他のすべてのプロダクションコードはそのまま残すことができます。

言い換えれば、モックフレームワークのトリックを使用してデザインの問題を「修正」しないでください。

関連する問題