简体   繁体   English

JUnit FindById 返回空指针(Mockito)

[英]JUnit FindById returns null pointer (Mockito)

I'm trying to write a JUnit test for one of my services in my project but I'm getting a NULL POINTER EXCEPTION every time that I run it.我正在尝试为我的项目中的一项服务编写 JUnit 测试,但是每次运行它时我都会收到一个 NULL POINTER EXCEPTION。

Can anyone please tell me what's wrong with my code ???谁能告诉我我的代码有什么问题???

The service is that I'm trying to cover is :我试图涵盖的服务是:

    public City findById(Long cityId) {
        logger.info("City find by ID : {}", cityId);
        return cityDao.findById(cityId)
                .orElseThrow(() -> new ResourceNotFoundException(ErrorMessageEN.NO_CITY_FOUND_IN_DB));
    }

The JUnit is: JUnit 是:

import static org.mockito.Mockito.when;
import java.util.Optional;
import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
class CityServiceImplTest {
    @InjectMocks
    private CityService cityService;

    @Mock
    private CityDao cityDao;

    private City city = new City();
    private Region region = new Region();

    @Before
    public void init() {
        city.setId(1L);
        city.setPinCode("1234");
        city.setCityName("Mumbai");

        region.setId(1L);
        region.setRegionName("Test");

        city.setRegion(region);
        MockitoAnnotations.initMocks(this);
    }

    @Test
    void findById_SUCCESS() {
        when(cityDao.findById(1L)).thenReturn(Optional.of(city));
        cityService.findById(1L);
    }
}

This is the stack trace of it :这是它的堆栈跟踪:

java.lang.NullPointerException
    at com.recupmespoints.api.service.impl.CityServiceImplTest.findById_SUCCESS(CityServiceImplTest.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
    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:104)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
    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:202)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
    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:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    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: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:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    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: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:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    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.DefaultLauncher.execute(DefaultLauncher.java:229)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

You have a couple of issues with your test class:您的测试类有几个问题:

  • Minor one: You don't need to use MockitoAnnotations.initMocks(this);次要一:你不需要使用MockitoAnnotations.initMocks(this); and @RunWith(MockitoJUnitRunner.class) together.@RunWith(MockitoJUnitRunner.class)在一起。 They are basically doing the same thing.他们基本上都在做同样的事情。
  • Major one: Your test class must be public : public class CityServiceImplTest {...}主要一:你的测试类必须是publicpublic class CityServiceImplTest {...}

  • Another major one: You are using a JUnit 4 runner org.mockito.junit.MockitoJUnitRunner with JUnit 5 annotation org.junit.jupiter.api.Test .另一个主要问题:您正在使用 JUnit 4 运行程序org.mockito.junit.MockitoJUnitRunner和 JUnit 5 注释org.junit.jupiter.api.Test I suggest sticking to JUnit 4 by importing org.junit.Test instead.我建议通过导入org.junit.Test来坚持 JUnit 4。

A Simplified version of your test in JUnit 4 would be: JUnit 4 中测试的简化版本将是:

import static org.mockito.Mockito.when;

import java.util.Optional;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class CityServiceImplTest {

  @InjectMocks
  CityService cityService;

  @Mock
  CityDao cityDao;

  private City city = new City();

  @Before
  public void init() {
    city.setId(1L);
    city.setPinCode("1234");
    city.setCityName("Mumbai");
  }

  @Test
  public void findById() {
    when(cityDao.findById(1L)).thenReturn(Optional.of(city));
    cityService.findById(1L);
  }
}

But if you want to go with JUnit 5 you have to use @BeforeEach and @ExtendWith(MockitoExtension.class) :但是如果你想使用 JUnit 5 你必须使用@BeforeEach@ExtendWith(MockitoExtension.class)

import java.util.Optional;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class CityServiceImplTest {

  @InjectMocks
  CityService cityService;

  @Mock
  CityDao cityDao;

  private City city = new City();

  @BeforeEach
  public void init() {
    city.setId(1L);
    city.setPinCode("1234");
    city.setCityName("Mumbai");
  }

  @Test
  public void findById() {
    when(cityDao.findById(1L)).thenReturn(Optional.of(city));
    cityService.findById(1L);
  }
}

尝试使用 import org.junit.Test 而不是 import org.junit.jupiter.api.Test 因为 @org.junit.runner.RunWith 不是来自 junit5

Your init() method is tagged with org.junit.Before annotation, but the test overall is run using JUnit 5, which does not recognize the method to be invoked as part of setup procedure.您的init()方法使用org.junit.Before注释进行标记,但整个测试是使用 JUnit 5 运行的,它无法识别要作为设置过程的一部分调用的方法。 Meaning MockitoAnnotations.injectMocks is never called as well.意思是MockitoAnnotations.injectMocks也不会被调用。

If you wish to use JUnit5, you should annotate your setup with @BeforeEach , as it is an equivalent annotation from JUnit 5.如果您想使用JUnit5,你应该注释你的设置@BeforeEach ,因为它是从JUnit的5等效的标注。

Alternatively, you can go with what other users already suggested and stick with JUnit 4 API.或者,您可以采用其他用户已经建议的方法并坚持使用 JUnit 4 API。

The main point is - don't mix JUnit versions, even if that works, it's by accident.重点是 - 不要混合 JUnit 版本,即使它有效,也是偶然的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM