2016-07-20 40 views
1

私は非常に複雑なクラスをJunitテストケースを記述する必要があります。テストを実行するクラスにコンストラクタの初期化があるので、PowerMockitoを使用することにしました。PowerMockito InjectMocksエラーを使用して

私のメインクラスは、このようなものです:

public class MainClass extends BaseClass{ 

MainClass(SomeClass class){ 
    super(class); 
} 

public void methodToBeTested(){ 
some code here 
} 

..few other methods which I am not going to test. 
} 

今、私はこのように書かれたテストケースを持っている:

@RunWith(PowerMockRunner.class) 
public class TestClass{ 

@Mock 
OtherClassUsedInMainClass mock1; 

@Mock 
OtherClassUsedInMainClass mock2; 

@InjectMocks 
MainClass mainClass; 

@Before 
public void setUp() throws Exception{ 
    MockitoAnnotations.initMocks(this); 
    PowerMockito.whenNew(MainClass.class).withArguments(Mockito.any(SomeClass.class)) 
      .thenReturn(mainClass);) 
} 

@Test 
public void testMethodtobeTested(){ 
    ...I am using the other objects to mock data and test if this method works fine 

    mainClass.methodtobeTested(); 
    \\This method will increment a value. I am just asserting if that value is right. 
    Assert.assertEquals(mainClass.checkCount(),RequiredCount) 

} 

} 

それ以来、テストケースを実行しているとき、私はnullポインタ例外を取得していますmainClassを初期化しようとしています。それは嘲笑されません。私は何か間違っていることを知っています。しかし、私はそれが何であるか分かりません。

エラー:

org.mockito.exceptions.base.MockitoException: 
Cannot instantiate @InjectMocks field named 'mainClass' of type 'class com.main.MainClass'. 
You haven't provided the instance at field declaration so I tried to construct the instance. 
However the constructor or the initialization block threw an exception : null 

Caused by: java.lang.NullPointerException 
This null pointer exception is thrown from a the constructor of the BaseClass when it tries to initialize another class. 
+0

はBaseClassののコンストラクタを表示します。そこにエラーが発生する – Jens

+0

なぜあなたはメインクラスをスタブしていますか?あなたがテストしているクラスではありませんか? –

+0

@Jens基本クラスのコンストラクタは、mainClassから渡されたsomeClassを引数として受け取ります。また、このsomeClassを使用して、someClassを使用するコンストラクタも持つ他のいくつかのクラスを初期化するためにこのsomeClassを使用します。 – v1shnu

答えて

0

@InjectMocks documentationを引用され、this answerを引用:

Constructor injection; the biggest constructor is chosen, then arguments are resolved with mocks declared in the test only. Note: If arguments can not be found, then null is passed.

だから、おそらく、タイプSomeClassのフィールドを宣言し、それ@Mockに注釈を付けます。

1

This question@Mock@InjectMocksの違いを説明しています

@Mockはモックを作成します。 @InjectMocksはクラスのインスタンスを作成し、@Mock(または@Spy)アノテーションで作成されたモックをこのインスタンスに挿入します。

MainClassコンストラクタはSomeClassパラメータを期待していますが、そのためのモックはありません。

あなたのコードのようなものでなければなりません:あなたは私たちに起こっている正確に何を推測することは非常に困難である実際のコードを表示できない場合

@RunWith(PowerMockRunner.class) 
public class TestClass{ 

    @Mock(answer = Answers.RETURNS_DEEP_STUBS) 
    SomeClass mock1; 

    @InjectMocks 
    MainClass mainClass; 

    @Before 
    public void setUp() throws Exception{ 
    ... 
+0

私はこれをしました。しかし、コードはまだBaseClassに入っています。私はBaseClassからnullポインタを取得してinitを試みます。 – v1shnu

+0

@ViChUこれは違うと思っています。それは、ベースクラスがそのモックを使用する方法と関係があります。おそらく、SomeClassのメソッドから返されたオブジェクトで何かをやっています。 @Mockを使ってみてください(回答= Answers.RETURNS_DEEP_STUBS) – user1121883

+0

私はこれを試しました。それはまだBaseClassからnullをスローします。MainClass constがsuper(someClass)を呼び出すと、someClassでBaseClass constを呼び出します。コンストラクタ内には、いくつかのオブジェクトが作成されています。 someClassオブジェクトにアクセスするものと、someClassをコンストラクタで使用するものがあります。 – v1shnu

0

。しかし、あなたのモックのように見えるSomeClassは、BaseClassコンストラクタを満たすためにいくつかのスタッブされた動作が必要です。例えば

// the instance of MainClass you run your tests against 
private MainClass instance; 

@Mock 
private SomeClass someClass; 
@Mock 
private SomethingElse somethingElse; 

@Before 
public void setUp() { 
    when(someClass.doSomething()).thenReturn(somethingElse); 
    instance = new MainClass(someClass); 
} 

@Test 
public void test() { 
    // SETUP 
    when(somethingElse.doWeirdStuff()).thenThrow(new WeirdException()); 

    // CALL 
    instance.performTapDance(); 

    // VERIFY 
    assertTrue(instance.isWeird()); 
} 
関連する問題