Nullpointer beim Mocken meiner jOOQ Datenbank

chris080

Mitglied
Ich verwende Vaadin, eine jOOQ Datenbank und will eine Methode testen, dessen Datenbankzugriff gemockt werden soll. Mein Code:

Java:
package de.phoneresearchfield.prf2.web.vaadin.views;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.when;
import org.jooq.DSLContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.BeforeEach;

import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;
import de.phoneresearchfield.prf2.web.domain.tables.records.MethodUsedRecord;
import de.phoneresearchfield.prf2.web.vaadin.views.admin.MethodUsedEditView;
import de.phoneresearchfield.prf2.web.domain.Tables;
@ExtendWith(MockitoExtension.class)
public class MethodUsedEditViewTest {
    @Mock
    private DSLContext dslContextMock;
    @InjectMocks
    private MethodUsedEditView methodUsedEditView;
    @BeforeEach
    public void setUp() {
        MockitoAnnotations.openMocks(this);
        this.methodUsedEditView = new MethodUsedEditView(dslContextMock);
    }
    @Test
    public void testCheckIfNewMethodUsedAlreadyExistsSuccess() {
        MethodUsedRecord methodUsedRecordMock = Mockito.mock(MethodUsedRecord.class);
        Mockito.when(methodUsedRecordMock.getDescription()).thenReturn("methodUsed1");
        methodUsedRecordMock.setDescription("methodUsed1");
        assertNotNull(Tables.METHOD_USED);
        assertNotNull(Tables.METHOD_USED.DESCRIPTION);
        when(dslContextMock
            .selectFrom(Tables.METHOD_USED)
            .where(Tables.METHOD_USED.DESCRIPTION.eq("methodUsed1"))//<--- Nullpointer-Exception
            .fetchOne())
            .thenReturn(methodUsedRecordMock);
     
        boolean methodUsedRecordAlreadyExists = methodUsedEditView.checkIfNewMethodUsedAlreadyExists(methodUsedRecordMock);
    }
}

In Zeile 38 wird mir dann ein Nullpointer geworfen. Kann bei Bedarf auch den Error-Stacktrace ausgeben. Debuggen hat mir gar nicht geholfen. Googlen hat auch nicht viel gebracht und ich verstehe auch allgemein nicht, wieso dort ein Nullpointer geworfen wird. Gebe ich hier nicht nur das Verhalten an, was geschehen soll, wenn dieser Aufruf getätigt wird?
Ich hoffe jemand kann mir helfen.
 
Das wäre der hier
Java:
%TESTC  1 v2
%TSTTREE2,de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest,true,1,false,1,MethodUsedEditViewTest,,[engine:junit-jupiter]/[class:de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest]
%TSTTREE3,testCheckIfNewMethodUsedAlreadyExistsSuccess(de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest),false,1,false,2,testCheckIfNewMethodUsedAlreadyExistsSuccess(),,[engine:junit-jupiter]/[class:de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest]/[method:testCheckIfNewMethodUsedAlreadyExistsSuccess()]
%TESTS  3,testCheckIfNewMethodUsedAlreadyExistsSuccess(de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest)

%ERROR  3,testCheckIfNewMethodUsedAlreadyExistsSuccess(de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest)
%TRACES
java.lang.NullPointerException
        at de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest.testCheckIfNewMethodUsedAlreadyExistsSuccess(MethodUsedEditViewTest.java:51)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
        at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
        at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
        at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
        at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
        at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
        at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
        at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
        at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
        at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
        at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
        at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
        at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
        at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
        at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
        at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
        at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
        at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:40)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:529)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:757)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
        at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

%TRACEE

%TESTE  3,testCheckIfNewMethodUsedAlreadyExistsSuccess(de.phoneresearchfield.prf2.web.vaadin.views.MethodUsedEditViewTest)

%RUNTIME1669
 
Achso.

Java:
        when(dslContextMock
            .selectFrom(Tables.METHOD_USED)
            .where(Tables.METHOD_USED.DESCRIPTION.eq("methodUsed1"))//<--- Nullpointer-Exception
            .fetchOne())
            .thenReturn(methodUsedRecordMock);

Erstens, funktioniert so das Mocking nicht, wenn ich das richtig sehe. Du kannst nicht in einem when mehrere Aufrufe stapeln.

Zweitens, ist dslContextMock ein Mock, also selectFrom retourniert null.

Ich glaube so waere es richtiger (grob, pseudo-code):

Java:
        when(dslContextMock).selectFrom(Tables.METHOD_USED).thenReturn(dslContextMock);
        when(dslContextMock).where("methodUsed1").thenReturn(dslContextMock);
        when(dslContextMock).fetchOne().thenReturn(methodUsedRecordMock);

Du musst natuerlich jeden Aufruf mocken welcher gemacht wird.
 
Das hab ich ausprobiert, aber .selectFrom kann ich nur auf dslContextMock aufrufen.

Aber der Fehler saß tatsächlich wie immer vor dem Bildschirm. Ich habe in der zu testenden Funktion fetchOne() verwendet ...
Java:
MethodUsedRecord fetchecMethodUseRecord = dslContext.fetchOne(Tables.METHOD_USED, Tables.METHOD_USED.DESCRIPTION.eq(...))

Daher habe ich jetzt
Code:
when(dslContextMock
    .fetchOne(Tables.METHOD_USED, Tables.METHOD_USED.DESCRIPTION.eq("methodUsed1")))//<--- Keine Nullpointer-Exception mehr :-)
    .thenReturn(methodUsedRecordMock);

und es klappt jetzt. Also mit dem richtigen assert, das ich dann ergänzt habe.
 

Zurück
Oben