2016-08-09 21 views
4

私のJavaアプリケーション内でテストするためにMockitoを使用しています。Mockto:コンストラクタが呼び出されたことをテストする方法は?

どのようにしてコンストラクタが呼び出されたかをテストできますか?それは、例えば同様の方法を持っていないよう

verify(myclass, times(1)).doSomething(anotherObject); 

しかし、私は、コンストラクタを確認カントと呼ばれていました:私はこれに似て検証を行うにしようとしています

doSomething()

+0

私は、コンストラクタを呼び出さないとオブジェクトを取得できません。それは言語機能です。 –

+1

あなたは何を意味するのかを説明してください – java123999

+0

実際にテストしようとしていることを記述して、コンストラクタをモックする必要があると考えさせました。本当の必要がなければ私は驚かないだろう。 –

答えて

8

これは、作成されるオブジェクトがモックされたオブジェクトではないため、Mockitoでは実行できません。これはまた、その新しいオブジェクトで何かを検証することもできないことを意味します。

このシナリオでは、オブジェクトを新規作成するのではなくFactoryを使用して作成しました。 Factoryを模擬して、テストに必要なオブジェクトを返すことができます。

あなたのテストに合うようにデザインを変更してもどうかはあなた次第です!

+0

これは最善の解決策です。この問題を解決するためにFactoryクラスを将来的に使用するように見てください – java123999

+0

モックライブラリの制限を回避するための工場を紹介しています。これは明らかに良い解決策ではありません。代わりに、SUTからインスタンス化されているクラスを模擬する必要があると思わないようにすることをお勧めします。通常、嘲笑をしないでより良いテストが可能です。 –

0

コンストラクタは、オブジェクトが失敗した場合にオブジェクトを返しません。失敗した場合、プログラムはクラッシュする可能性があります。タフ

私は、これはそれを行うだろうとします

Object obj = null; 

obj = new Object(); 

if (obj == null) { 
    //... Didn't Work 
} else { 
    //... Worked 
} 
+3

OPはコンストラクタが動作することを確認する方法を尋ねるのではなく、実際にコンストラクタを呼び出す他のコードがあるかどうかを確認する方法を尋ねています。 –

1

verify()方法は嘲笑オブジェクト(すでに作成されたオブジェクト)を待ちます。 constructorcreated objectで呼び出すことはできません。

1

これはMockitoでは不可能であり、悪いデザインのように聞こえます。

ファクトリを使用してテスト対象オブジェクトに渡すことができます。その後、簡単にファクトリをモックし、createメソッドが呼び出されたことを確認できます。

コードにオブジェクトを直接作成することで、具体的な実装に強く依存しているため、単体テストではコードが難しくなり、時には不可能になります。これは、依存性注入(DI)および制御の反転(IoC)で対処されています。

0

あなたはmockitoでコンストラクタをモックすることはできませんが、powermockitoを使用するとできることがあります。セットアップはMockitoとPowerMockitoでそれを行うことができ、この

public class MyClass{ 

    public MyClass(String name){} 

    public void doSomethingUseFul(){ 
     //....... 
    } 

} 

public class Helper { 

    public void goHelp(){ 
     new MyClass("apple").doSomethingUseFul(); 
    } 

} 

//モック

@RunWith(PowerMockRunner.class) 
    @PrepareForTest(MyClass.class) 
    public class MockMyClass { 
    @InjectMocks 
    private Helper helper; 

     @Test 
     public void testDoSomethingUseFul() { 
      MyClass c = mock(MyClass.class); 
      doNothing().when(c).doSomethingUseFul(); 
      PowerMockito.whenNew(MyClass. class).withArguments(anyString()).thenReturn(c); 
      helper.goHelp(); 
      verifyNew(MyClass.class).withArguments(anyString()) 


     } 
    } 
8

ようなものになるだろう。

あなたは、コンストラクタ

public class ClassUnderTest { 
    String name; 
    boolean condition; 

    public ClassUnderTest(String name, boolean condition) { 
     this.name = name; 
     this.condition = condition; 
     init(); 
    } 

    ... 
} 

そして、我々はできるテストクラスでコンストラクタ

public class MyClass { 

    public MyClass() { } 

    public void createCUTInstance() { 
     // ... 
     ClassUnderTest cut = new ClassUnderTest("abc", true); 
     // ... 
    } 

    ... 
} 

ことを呼び出し、別のクラスでClassUnderTestを持っていると言います...

(1)PowerMockRunnerを使用しPrepareForTest注釈上記両方のターゲットクラスを引用:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ ClassUnderTest.class, MyClass.class }) 
public class TestClass { 

(2)モックオブジェクトを返すためのコンストラクタインターセプト:

@Before 
public void setup() { 
    ClassUnderTest cutMock = Mockito.mock(ClassUnderTest.class); 
    PowerMockito.whenNew(ClassUnderTest.class) 
       .withArguments(Matchers.anyString(), Matchers.anyBoolean()) 
       .thenReturn(cutMock); 
} 

(3)検証をコンストラクタ呼び出し:

@Test 
public void testMethod() { 
    // prepare 
    MyClasss myClass = new MyClass(); 

    // execute 
    myClass.createCUTInstance(); 

    // checks if the constructor has been called once and with the expected argument values: 
    String name = "abc"; 
    String condition = true; 
    PowerMockito.verifyNew(ClassUnderTest.class).withArguments(name, condition); 
} 
+0

私は、あなたのtestMethod()の最後の2行の順序が入れ替えるべきだと思います。次のようにします:new ClassUnderTest(name、condition); PowerMockito.verifyNew(ClassUnderTest.class); –

+0

@WillieZ、このテスト方法について私の注意を呼んでくれてありがとう!実際には、前回の最後のコマンドは本当に必要ではありませんでした。元の考えは、実行フェーズで呼び出されたテスト中のメソッドで、特定の引数値を使ってコンストラクタ呼び出しをテストすることでした。私は元の意図を表現するコードを書き直しました。今はっきりしていることを願っています。 –

関連する問題