2016-02-27 109 views
2

我試圖測試下面的類:NullPointerException異常的構造函數定義

public final class ClassA { 

    private final ClassB member; 

    public ClassA() { 
    this.member = new ClassB(); 
    } 

} 

以下是測試類:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ClassA.class, ClassB.class}) 
public final class ClassATest { 

    @Mock 
    private ClassB mocked; 

    private ClassA testClass; 

    @Before 
    public void initTest() { 
    PowerMockito.whenNew(ClassB.class).withNoArguments().thenReturn(mocked); 
    testClass = new ClassA(); 
    } 

現在的問題是,我得到一個NullPointerException,它的堆棧跟蹤看起來像:

java.lang.NullPointerException 
    [junit]  at a.a.i.ClassA.<init>(ClassA.java:44) 
    [junit]  at a.a.i.ClassATest.init(ClassATest.java:53) 
    [junit]  at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    [junit]  at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    [junit]  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    [junit]  at java.lang.reflect.Method.invoke(Method.java:606) 
    [junit]  at org.junit.internal.runners.MethodRoadie.runBefores(MethodRoadie.java:132) 
    [junit]  at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:95) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:294) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:127) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:282) 
    [junit]  at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:86) 
    [junit]  at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:49) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:207) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:146) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:120) 
    [junit]  at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:33) 
    [junit]  at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:45) 
    [junit]  at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:122) 
    [junit]  at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:106) 
    [junit]  at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) 
    [junit]  at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59) 
    [junit]  at junit.framework.JUnit4TestAdapter.run(JUnit4TestAdapter.java:38) 
    [junit]  at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:532) 
    [junit]  at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1165) 
    [junit]  at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:988) 

ClassA的44行是 public Class A(){

ClassATest的第52行是 testClass = new ClassA();

我從來沒有遇到過構造函數定義的NullPointerException,所以我不知道該怎麼做。任何幫助將不勝感激。

+0

什麼是ClassB構造函數? – BlueMoon93

+0

B類的定義是什麼? – Ankur1994a

+0

ClassB具有默認的構造函數(未明確覆蓋) – Ulrich

回答

-3

我想,當你聲明的成員作爲最終ü應該初始化它馬上 嘗試這樣做,纔去構造,看看會發生什麼

+4

你猜錯了。 'final'實例字段可以在構造函數中設置。 (通常,*猜測*不是有用的答案。* –

0

我知道,問題是關於NPE,但而不是解決這個問題你應該重新考慮你的測試策略。爲什麼?

如果ClassA負責ClassB實例的創建和生命,並且您決定不注入ClassB的對象,那麼爲什麼要試圖嘲笑它呢?你的測試不應該依賴實現的細節,所以如果你不是在任何地方注入它,你都不應該嘲笑ClassB。

0

這種方法根本不值得推薦。對象不應該負責創建自己的依賴關係。它們應該在構造函數中提供(或通過setter方法)。

我會建議你改變你的構造類似這樣的

public final class ClassA { 

    private final ClassB member; 

    public ClassA(ClassB member) { 
    this.member = member; 
    } 

} 

在你想保持你的代碼,你可以添加在測試中使用的構造情況下(雖然只用於測試目的添加的代碼是不是推薦)

public final class ClassA { 

    private final ClassB member; 

    public ClassA() { 
    this(new ClassB()); 
    } 

    // Default visibility so it's only visible in its package 
    // Added for testing purposes 
    ClassA(ClassB member) { 
    this.member = member; 
    } 

}