-1

The class that I want to test is structured in the following manner:

public getUrl(final String str1, final String str2, final String str3, final int int1, final String string4) {
//calls getContext();
}

public getUrlAndAppend(final String str1, final String str2, final String str3, final int int1, final String string4, final Map<String, String> map){
//calls getUrl();
}

private getContext(final String str1, final String str2, final String str3, final int int1, final String string4);

All the 3 methods have the exact same set of parameters with the exception of getUrlAndAppend() that has an extra Map.

I am trying to test only the getUrlAndAppend() method which is calling the public getUrl() that eventually calls the private method getContext(). This is my test class so far:

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest{

  MyClass myClass = Mockito.spy(new MyClass(new MyClass2()));

  @Test
  void shouldGenerateUrl() {

    when(myClass.getUrl(anyString(), anyString(), anyString(), anyInt(), anyString())).thenReturn("http://www.url.com");
    String result = myClass.getUrlAndAppend("test", "test", "test", 1, "test", null);
    assertThat(result).isEqualTo("http://www.url.com");
  }
}

Why is the above code is throwing an NPE inside the private method that's getting called from the getUrl() method, even though I'm specifying what has to be returned when getUrl() is called? I didn't want to use the Mock annotation in MyClass because I want to test the behavior of my getUrlAndAppend() method, so I decided to use @Spy.

Stack Trace:

java.lang.NullPointerException
    at path$UrlContextBuilder.build(MyClass3.java:168)
    at path.MyClass.getContext(MyClass.java:104)
    at path.MyClass.getUrl(MyClass.java:32)
    at path.MyClassTest.shouldGenerateUrlWithAspectsAppended(MyClassTest.java:24)
    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:1540)
    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:1540)
    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:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Marcos Guimaraes
  • 1,243
  • 4
  • 27
  • 50
  • 1
    The code of `MyClass` is missing essential parts, namely method `geturl(String, String, String, int, String)`. Please [edit] the post and add the post. --- Please read: [Why is “Can someone help me?” not an actual question?](https://meta.stackoverflow.com/questions/284236/why-is-can-someone-help-me-not-an-actual-question) --- A remark: we should favor mockito's `when(...).thenReturn(...)` syntax over `doReturn(...).when(...)` since the former guarantees type safety. – Turing85 Dec 08 '22 at 00:35
  • Hey, thanks for the reply. I have edited my question and added the missing parameters for the methods. I have already tried when(...).thenReturn(...) but I've got the same result. – Marcos Guimaraes Dec 08 '22 at 00:39
  • 1
    What does `getContext()` do? Also, please [edit] the post and add the stack trace. Something is not properly initialized. And `@Spy` will not work this way. What you want is most probably `MyClass myClass = Mockito.spy(new MyClass(new MyClass2()));` – Turing85 Dec 08 '22 at 00:39
  • 1
    Yep, pretty sure that this is due to the wrong spy initialization. Please try using `MyClass myClass = Mockito.spy(new MyClass(new MyClass2()));` and remove the annotation. – Turing85 Dec 08 '22 at 00:52
  • Hi Turing85, thanks for the help. I tried replacing the initialization of the spied object following your suggestion, but I'm still facing the same issue. A NPE is getting thrown inside the private method getUrlContext(). I have updated the code with the latest changes. – Marcos Guimaraes Dec 08 '22 at 02:07
  • The error is happening inside the "when" clause after calling getUrl(). The private method is responsible for calling other classes to build the response based on the parameters. All the String parameters are empty and the integer is 0 when getUrl() is called. – Marcos Guimaraes Dec 08 '22 at 02:12
  • Why are you mocking the class which you are testing? That feels wrong … – knittl Dec 08 '22 at 14:44

1 Answers1

0

What actually worked for me was using this:

Mockito.doReturn("http://www.url.com").when(myClass).getUrl(anyString(), anyString(), anyString(), anyInt(), anyString());

Thanks @Turing85 for also helping me through this.

This is the full test class:

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyString;

@RunWith(MockitoJUnitRunner.class)
public class MyClassTest{

  MyClass myClass = Mockito.spy(new MyClass(new MyClass2()));

  @Test
  void shouldGenerateUrl() {

  @Test
  void shouldGenerateUrlWithAspectsAppended() {
    Mockito.doReturn("http://www.url.com").when(myClass).getUrl(anyString(), anyString(), anyString(), anyInt(), anyString());
    String result = myClass.getUrlAndAppend("1234", "test", "test", 1, "test", null);
    assertThat(result).isEqualTo("http://www.url.com");
  }
}
Marcos Guimaraes
  • 1,243
  • 4
  • 27
  • 50