简体   繁体   中英

Mockito Spring Boot gives Null Pointer Exception

I am unable to run a unit test for my spring boot application at the Service Layer as it gives me null pointer exception at line List<Student> expectedList = studentService.findAl(); . But if I invoked the mock directly it works List<Student> expectedList = studentRepository.findAll(); . The studentRepository is inject in the studentService. Can anyone illustrate what the problem is?
TestClass:

import com.demo.student.demo.entity.Student;
import com.demo.student.demo.repository.StudentRepository;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import static org.mockito.Mockito.*;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;

public class StudentServiceImplTest {

    @Mock
    private StudentRepository studentRepository;

    @InjectMocks
    private StudentServiceImpl studentService;

    @Test
    public void findAll(){
        List<Student> studentList = new ArrayList<>();
        studentList.add(new Student(1, "person1", "person1@mail.com"));
        studentList.add(new Student(2, "person2", "person2@mail.com"));

        when(studentRepository.findAll()).thenReturn(studentList);

        List<Student> expectedList = studentService.findAl();

        assertEquals(0, expectedList.size());
    }


}

and the Repository:

@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
}

the service interface:

public interface StudentService {

    public List<Student> findAl();
    public Student findById(long id);
    public Student saveOrUpdate(Student student);
    public void deleteById(long id);

}

and the service implementation:

@Service
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentRepository studentRepository;

    @Override
    public List<Student> findAl() {
        return studentRepository.findAll();
    }

    @Override
    public Student findById(long id) {
        Optional<Student> student = studentRepository.findById(id);
        boolean exist = student.isPresent();
        return exist? student.get() : null;
    }

    @Override
    public Student saveOrUpdate(Student student) {
        studentRepository.save(student);
        return student;
    }

    @Override
    public void deleteById(long id) {
        studentRepository.deleteById(id);
    }

}

I did some modifications to your code. The change that I did was in the StudentServiceImpl class. I removed the @Autowired annotation and did constructor injection.

@Service
public class StudentServiceImpl implements StudentService {

private final StudentRepository studentRepository;

public StudentServiceImpl(StudentRepository studentRepository) {
    this.studentRepository = studentRepository;
}

//others are same
}

And in the test class.

@RunWith(MockitoJUnitRunner.class)
public class StudentServiceImplTest {

private StudentService studentService;
private StudentRepository studentRepository;

@Test
public void findAll(){
    studentRepository = mock(StudentRepository.class);
    studentService = new StudentServiceImpl(studentRepository);
    List<Student> studentList = new ArrayList<>();
    studentList.add(new Student(1, "person1", "person1@mail.com"));
    studentList.add(new Student(2, "person2", "person2@mail.com"));

    when(studentRepository.findAll()).thenReturn(studentList);

    List<Student> expectedList = studentService.findAl();

    assertEquals(2, expectedList.size());
 }
}

Now I can see the test passing.

在此处输入图像描述

Also, read this article which says "Get rid of @InjectMocks".

I hope it helps you:) Thanks a lot.

The mock you are configuring here:

    StudentRepository studentRepository = mock(StudentRepository.class);

Is not injected into the service. Remove the initialisation of studentRepository inside your test and just use the one you have already annotated with @Mock.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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