2016-07-11 13 views
1

Ich habe die folgende einfache Klasse: import javax.net.ssl.SSLContext;SSLContext Schein verhält sich nicht wie erwartet

public class AClass { 
    public void someMethod() throws Exception { 
     SSLContext context = SSLContext.getInstance("SSL"); 
     context.init(null, null, null); 
    } 
} 

Und seine JUnit: Import javax.net.ssl.SSLContext;

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mockito; 
import org.powermock.api.mockito.PowerMockito; 
import org.powermock.core.classloader.annotations.PrepareForTest; 
import org.powermock.modules.junit4.PowerMockRunner; 

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ SSLContext.class }) 
public class ATest { 
    @Test 
    public void testSomeMethod() throws Exception { 
     PowerMockito.mockStatic(SSLContext.class); 
     SSLContext context = Mockito.mock(SSLContext.class); 
     Mockito.when(context.getInstance("SSL")).thenReturn(context); 
     new AClass().someMethod(); 
    } 
} 

JUnit schlägt mit der folgenden Stapelüberwachung:

java.lang.NullPointerException 
    at javax.net.ssl.SSLContext.init(Unknown Source) 
    at random.AClass.someMethod(AClass.java:8) 
    at random.ATest.testSomeMethod(ATest.java:20) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
    at java.lang.reflect.Method.invoke(Unknown Source) 
    at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:316) 
    at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:89) 
    at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:97) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.executeTest(PowerMockJUnit44RunnerDelegateImpl.java:300) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTestInSuper(PowerMockJUnit47RunnerDelegateImpl.java:131) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.access$100(PowerMockJUnit47RunnerDelegateImpl.java:59) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner$TestExecutorStatement.evaluate(PowerMockJUnit47RunnerDelegateImpl.java:147) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.evaluateStatement(PowerMockJUnit47RunnerDelegateImpl.java:107) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit47RunnerDelegateImpl$PowerMockJUnit47MethodRunner.executeTest(PowerMockJUnit47RunnerDelegateImpl.java:82) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$PowerMockJUnit44MethodRunner.runBeforesThenTestThenAfters(PowerMockJUnit44RunnerDelegateImpl.java:288) 
    at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:87) 
    at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:50) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.invokeTestMethod(PowerMockJUnit44RunnerDelegateImpl.java:208) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.runMethods(PowerMockJUnit44RunnerDelegateImpl.java:147) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl$1.run(PowerMockJUnit44RunnerDelegateImpl.java:121) 
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:34) 
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:44) 
    at org.powermock.modules.junit4.internal.impl.PowerMockJUnit44RunnerDelegateImpl.run(PowerMockJUnit44RunnerDelegateImpl.java:123) 
    at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.run(JUnit4TestSuiteChunkerImpl.java:121) 
    at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.run(AbstractCommonPowerMockRunner.java:53) 
    at org.powermock.modules.junit4.PowerMockRunner.run(PowerMockRunner.java:59) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 

die Stapelüberwachung zeigt auf die Zeile mit context.init(null, null, null); einen Null-Zeiger aufweisen. Aber wenn ich (in Eclipse) debugge, kann ich deutlich sehen, dass der Wert der context Variable ein Mock for SSLContext, hashCode: 1857173583 ist. Wenn ein Mock, dann eine void-Methode wie init() sollte nichts tun. Also, warum wirft es eine NullPointerException?

Antwort

2

Mit Blick auf die API und dekompilierten Signatur für die init Verfahren, das die NPE wirft, zeigt es als endgültige, welche basische Mockito.mock() can not handle.

Final method

Auf der anderen Seite ist die Javadoc- für PowerMockito.mock() lautet:

org.powermock.api.mockito.PowerMockito

public static T mock (Class-Typ)
ein Mock-Objekt erzeugt, das Verspottung endgültige unterstützt und native Methoden.

Typ Parameter:
        T - die Art des Mock-Objekt
Parameter:
        Typ - der Typ des Mock-Objekt
Returns:
        das Mock Objekt.

@RunWith(PowerMockRunner.class) 
@PrepareForTest({SSLContext.class}) 
public class ATest { 
    @Test 
    public void testSomeMethod() throws Exception { 
     // create the mock to return by getInstance() 
     SSLContext context = PowerMockito.mock(SSLContext.class); 

     // mock the static method getInstance() to return above created mock context 
     PowerMockito.mockStatic(SSLContext.class); 
     Mockito.when(SSLContext.getInstance("SSL")).thenReturn(context); 

     // invoke the object under test 
     new AClass().someMethod(); 

     //TODO - add verifications/assertions 
    } 
} 

Update::

Also, ein bisschen Ihren Test Wechsel sollte es funktioniert

Da Sie den Test mit dem PowerMockRunner laufen lassen, Sie kann auch ersetzen

SSLContext context = PowerMockito.mock(SSLContext.class); 

mit einem Feld

@Mock 
private SSLContext context; 

die auch von PowerMock behandelt werden (oder MockitoJUnitRunner verwenden, wenn Sie nur grundlegende Mockito benötigen)

+0

Dachte immer, 'PowerMockito.mock()' '& Mockito.mock () 'waren die selben. Danke für das Aufzeigen! – Vineet

+1

@Vineet kein Problem, in der Tat, sie sind [ähnlich] (http://i.imgur.com/pIvKZxD.gif), mit powermock Hinzufügen von mehr Funktionen auf Mockito. Auch ich habe die Antwort mit einem zweiten Ansatz aktualisiert. – Morfic

Verwandte Themen