2016-11-17 3 views
0

Ich habe einen Vortragenden, der eine Methode getView() hat, die eine Ansicht zurückgibt. Die View, die MyView (eine Schnittstelle) implementiert, hat eine Methode isActive, die angibt, ob sie aktiv ist.Unit Test - Mockito gibt NullPointerException beim Mocking einer Schnittstelle

Ich teste den Presenter.

Im @Before Setup der TestClass initialisiere ich den Presenter.

testClass.java:

@RunWith(AndroidJUnit4.class) 
public class testClass { 
    private Presenter presenter; 
    @Mock 
    private MyView mockView; 

@Before 
public void setup() { 
    MockitoAnnotations.initMocks(this); 
    presenter = new Presenter(mockView); 
    when(mockView.isActive()).thenReturn(true); 
} 

@Test 
public void testIsActive() { 
    presenter.isViewActive(); 
    verify(mockView).isActive(); 
} 

Presenter.java:

public class Presenter { 
    private MyView view; 

    // The following view is an instance of MyView, not View (typo before). 
    public Presenter(MyView view) { 
     this.view = view; 
    } 

    public boolean isViewActive() { 
     return getView().isActive(); 
    } 

    public MyView getView() { 
     return view; 
    } 

} 

MyView.class:

public interface MyView { 
    boolean isActive(); 
} 

jedoch der obige Code würde Nullpointer erzeugen, wenn

presenter.isViewActive(); 

läuft.

Warum ist es?

Und wenn ich

ersetzen
@Mock 
private MyView mockView; 

mit

@Mock 
private ConcreteMyView mockView; 

wo ConcreteMyView eine Implementierung von Interface MyView ist, wird der Code reibungslos.

Irgendwelche Hinweise?

+0

Ich sehe, dass Sie in Presenter View als Konstruktorparameter betrachten. Aber Ihre Definition von MyView erstreckt sich nicht von View, also kompiliert sie nicht (kann this.view nicht auf View-Instanz setzen). Ist das ein Tippfehler im Code? – mdewit

+0

Hinweis, wenn ich im Presenter-Konstruktor die Ansicht zu MyView ändere, kompiliert der Testfall und läuft erfolgreich für mich – mdewit

Antwort

0

Ich mdewit bereits identifiziert Ihre getestete Klasse nimmt eine Ansicht (nicht gezeigt/definiert) anstelle von MyView.

Wenn Sie ein Problem haben, können Sie in den folgenden Code suchen und vergleichen.

public class SomeTest { 
    private Presenter presenter; 
    @Mock 
    private MyView mockView; 

    @Before 
    public void setup() { 
    MockitoAnnotations.initMocks(this); 
    presenter = new Presenter(mockView); 
    when(mockView.isActive()).thenReturn(true); 
    } 

    @Test 
    public void testIsActive() { 
    assertTrue(presenter.isViewActive()); 
    verify(mockView).isActive(); 
    } 

    private class Presenter { 
    private MyView view; 

    public Presenter(MyView view) { 
     this.view = view; 
    } 

    public boolean isViewActive() { 
     return getView().isActive(); 
     //return true; 
    } 

    public MyView getView() { 
     return view; 
    } 
    } 

    private interface MyView { 
    boolean isActive(); 
    } 
} 
+0

Sorry, ich habe die Antwort bis vor kurzem nicht bemerkt. Also folgern Sie, dass Mockito, wenn er die Schnittstelle MyView verspottet, da es keine konkrete Klasse ist, versucht, stattdessen seine Superklasse, die eine konkrete Klasse ist, zu verspotten? Es bedeutet also, dass wir eine Schnittstelle nicht falsch machen können. – Derekyy

+0

Nein, definitiv nicht. Es ist eigentlich eine gute Übung, Interfaces zu verspotten und es ist, was ich oben in den Code eingefügt habe. (MyView ist eine Schnittstelle und es wird verspottet). Das einzige Problem Ihres Codes besteht darin, dass Sie eine andere Klasse mit dem Namen 'Ansicht' verwenden (siehe Konstruktorparameter 'Presenter'). –

+0

Ich habe es bemerkt. Entschuldigung, es war nur ein Tippfehler, im tatsächlichen Fall ist die Ansicht im Presenter-Konstruktor tatsächlich eine Instanz von MyView. Deine Antwort ist also nicht korrekt – Derekyy

Verwandte Themen