2016-11-17 12 views
2

でテストメソッド呼び出しをスタブするとき、私はユニットテストではこれらの2行があります。NullPointerExceptionがMockito

DefaultMessageListenerContainer defaultMessageListenerContainer = Mockito.mock(DefaultMessageListenerContainer.class); 
when(defaultMessageListenerContainer.isRunning()).thenReturn(true); 

スタックトレース:どんなに

java.lang.NullPointerException 
    at org.springframework.jms.listener.AbstractJmsListeningContainer.isRunning(AbstractJmsListeningContainer.java:347) 
    at xxxxxxxxxxxxxx.MessageProcessorControllerTest.testPing(MessageProcessorControllerTest.java:109) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85) 
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:639) 
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816) 
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124) 
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) 
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108) 
    at org.testng.TestRunner.privateRun(TestRunner.java:774) 
    at org.testng.TestRunner.run(TestRunner.java:624) 
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:359) 
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354) 
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312) 
    at org.testng.SuiteRunner.run(SuiteRunner.java:261) 
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) 
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) 
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1191) 
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1116) 
    at org.testng.TestNG.run(TestNG.java:1024) 
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72) 
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:124) 

私は、NPEがwhenにスローされます何をスタブを設定するときに実際のメソッドが呼び出されているかのようになります。私はmockito v1.10.19を使用しています。何が間違っているのですか?

UPDATE:ここ 全体スタンドアロンのテストクラスである:

import org.mockito.Mockito; 
import org.springframework.jms.listener.DefaultMessageListenerContainer; 
import org.testng.annotations.Test; 

import static org.mockito.Mockito.when; 

public class JmsTest { 
    @Test 
    public void test() throws Exception { 
     DefaultMessageListenerContainer defaultMessageListenerContainer = Mockito.mock(
       DefaultMessageListenerContainer.class); 
     when(defaultMessageListenerContainer.isRunning()).thenReturn(true); 
    } 
} 

とスローされる例外:

java.lang.NullPointerException 
    at org.springframework.jms.listener.AbstractJmsListeningContainer.isRunning(AbstractJmsListeningContainer.java:347) 
    at xxxxxxxxxxx.util.JmsTest.test(JmsTest.java:17) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:85) 
    at org.testng.internal.Invoker.invokeMethod(Invoker.java:639) 
    at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:816) 
    at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1124) 
    at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125) 
    at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:108) 
    at org.testng.TestRunner.privateRun(TestRunner.java:774) 
    at org.testng.TestRunner.run(TestRunner.java:624) 
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:359) 
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:354) 
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:312) 
    at org.testng.SuiteRunner.run(SuiteRunner.java:261) 
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52) 
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:86) 
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1191) 
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1116) 
    at org.testng.TestNG.run(TestNG.java:1024) 
    at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:72) 
    at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:124) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:497) 
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147) 
+1

あなたのtestPingメソッドを表示できますか?そして '@ Before'や' @ BeforeClass'メソッドはありますか? –

+0

コードをデバッグしてみてください。ヌルポインタは "when"行にスローされるべきではありません。それは他のどこかにあるはずです。行番号を関連付けることができるように、テストクラスファイル全体を提供できますか? –

答えて

0

あなたdefaultMessageListenerContainerが使用されているものではありません。失敗したものはタイプAbstractJmsListeningContainerです。

mocked変数が、テストしようとしているクラスに正しく渡されていることを確認する必要があります。

+1

'AbstractJmsListeningContainer'を使うようにコードを変更すると、同じ結果が生成されます:' AbstractJmsListeningContainer defaultMessageListenerContainer = Mockito.mock( \t \t \t \t AbstractJmsListeningContainer.class); \t \t when(defaultMessageListenerContainer.isRunning())。then return(true); ' – Mensur

+0

問題を再現するスタンドアロンテストクラスを追加しました。私の更新を見てください。 – Mensur

0

これはいいですね!私はそれが期待を設定し、その後アサーションを作成しないように見えるので、テストをパスすることを期待していたでしょう。私は非常にシンプルな運動がうまくいかない理由について、Mockitoのエキスパートに任せておきたいと思います。私は確かにそれが何の背後にあるのか知ることに興味があるでしょう。その間、別のライブラリを使用するオプションがある場合は、代わりにこの提案を提供します:JMockitを試してみてください。以下は、あなたがMockitoで達成しようとしていたものとおおよそ同等になるはずですが、テストに合格します。がんばろう!

import mockit.Expectations; 
import mockit.Mocked; 
import org.junit.Test; 
import org.springframework.jms.listener.DefaultMessageListenerContainer; 

import static org.assertj.core.api.Assertions.assertThat; 

public class JmsTest2 { 

    @Mocked 
    DefaultMessageListenerContainer defaultMessageListenerContainer; 

    @Test 
    public void test() throws Exception { 
     new Expectations() {{ 
      defaultMessageListenerContainer.isRunning(); result = true; 
     }}; 
     assertThat(defaultMessageListenerContainer.isRunning()).isTrue(); 
    } 
} 

EDIT 1:

もう少し密接にこのを見ると、いくつかの同期は、最終的なマークされたオブジェクトの周りに()メソッドは、そのisRunningでありますようです。 Mockito、AFAIKは、あなたが変更したいfinalとマークされたオブジェクトを持っている場合に役立つものではありません。あなたはPowerMockでこれと戦おうとするか、別のライブラリを使うことができます - 私が好きなものを既に提案しました - 私はあなたにとってきれいで簡単な方法だと思います。

protected final Object lifecycleMonitor = new Object(); 
... 
@Override 
public final boolean isRunning() { 
    synchronized (this.lifecycleMonitor) { 
     return (this.running && runningAllowed()); 
    } 
} 
+0

私もそれを見ました。しかし、私はMockitoがそのメソッドの期間を呼び出すべきではないと考えていたので、その中にあるものは問題ではないはずです。 – Mensur

+0

これは良い質問でした。あなたのコードは、「最終的」の使用によって課された制約に支配されていない協力的なクラスのMockitoで可能なことをはっきりと表現していたからです。基本的に、あなたはMockitoが意図しているものを正確にやりたいと思っていますが(最終的な方法を扱うことができないという脚注を除いて)、妨げられています。あなたが交換したいメソッドが最終的だと気づくまで、私は、ああ、これはうまくいくと思った。最近のバージョンのMockitoのように見えます。 – unigeek

関連する問題