1

Here is my Test class with method failing with NullPointer.

    @ExtendWith(MockitoExtension.class)
class DishServiceTest {
    @Mock
    DishRepository dishRepository;
    @Mock
    RestaurantRepository restaurantRepository;

    @Autowired
    @InjectMocks
    DishService dishService;

    @Test
void shouldReturnAllDishesToday_whenGetAllToday() {
    Clock clock = Clock.systemDefaultZone();
    Mockito.when(dishRepository.getAllByDateAdded(LocalDate.now(clock))).thenReturn(getDishes());

    List<DishResponseDTO> resultList = dishService.getAllToday();

    assertEquals(4, resultList.size());
    assertEquals(getResponseDishes().get(3), resultList.get(3));
}

As you can see I even tried to initialize the clock right in the method, but it still fails.Here is my tested class with a method. It works as intended when I start the app.

   @Service
public class DishService {
    DishRepository dishRepository;
    RestaurantRepository restaurantRepository;
    Clock clock;
    @Autowired
public DishService(DishRepository dishRepository, RestaurantRepository restaurantRepository, Clock clock) {
    this.dishRepository = dishRepository;
    this.restaurantRepository = restaurantRepository;
    this.clock = clock;
}
        public List<DishResponseDTO> getAllToday() {
        List<Dish> dishlsit = dishRepository.getAllByDateAdded(LocalDate.now(clock)); // fails in tests here
        return dishlsit.stream()
                .map(DishMapper::toDishResponseDTO)
                .collect(Collectors.toList());

Here is the clock bean

    @Configuration
public class TimeConfig {
    @Bean
    public Clock clock() {
        return Clock.systemDefaultZone();
    }
}

Here is exception

java.lang.NullPointerException: clock

at java.base/java.util.Objects.requireNonNull(Objects.java:233)
at java.base/java.time.LocalDate.now(LocalDate.java:229)
at com.topjava.graduation.restaurant.service.DishService.getAllToday(DishService.java:42)
at com.topjava.graduation.restaurant.service.DishServiceTest.shouldReturnAllDishesToday_whenGetAllToday(DishServiceTest.java:71)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
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$6(TestMethodTestDescriptor.java:210)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
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:96)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

    }
user207421
  • 305,947
  • 44
  • 307
  • 483
  • 2
    The instance of clock is never initialized. The clock instance is not under Spring's control b/c it's not a bean. – duffymo Aug 28 '21 at 11:32
  • 1
    Yeah, AS @duffymo point out, you should mock clock also. It's better if you can use spring test, it can autowire real object and you only need to fake what you need to test. – Huy Nguyen Aug 28 '21 at 11:34
  • 1
    Why do you think Clock has to be injected in? I'd have a local scope object, not a Bean. What are you proving with this test? – duffymo Aug 28 '21 at 11:36
  • @duffymo I am really interested in understanding how to get this done. Even if i write MockBean Clock clock I get the same exception. Even if i write TestConfiguration and copy the code of the bean there and then Import(ServiceTestConfig.class) it still does not work –  Aug 28 '21 at 11:55
  • 1
    Don't inject it. Instantiate a local instance in the DishService method and get on with it. – duffymo Aug 28 '21 at 12:10
  • I am just wondering why does it work like that. If I write @SpringBootTest(classes = ServiceTestConfig.class) ( where is the bean of that class. And Autowired private Clock clock; Everything works perfectly. But with @Import and without SpringBootTest it does not. –  Aug 28 '21 at 12:45
  • @duffymo Injecting a `Clock` can make a lot of sense if you want to be able to control the clock for a test. – Mark Rotteveel Aug 29 '21 at 06:50
  • In that case it has to be a Soring bean. – duffymo Aug 29 '21 at 12:39

1 Answers1

0

duffymo is right in his comment.

You need to inject an instance of Clock into your DishService instance as well. As explained in this answer you can do this by using the @Spy annotation.