java - Mockito Spring Boot 给出空指针异常

标签 java spring unit-testing junit mockito

我无法在服务层为我的 Spring Boot 应用程序运行单元测试,因为它在 List<Student> expectedList = studentService.findAl(); 行给了我空指针异常。但如果我直接调用模拟,它就会起作用 List<Student> expectedList = studentRepository.findAll(); 。 StudentRepository 被注入(inject)到 StudentService 中。谁能说明问题是什么?
测试类:

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());
    }


}

和存储库:

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

服务接口(interface):

public interface StudentService {

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

}

以及服务实现:

@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);
    }

}

最佳答案

我对你的代码做了一些修改。 我所做的更改是在 StudentServiceImpl 类中。我删除了 @Autowired 注释并进行了构造函数注入(inject)。

@Service
public class StudentServiceImpl implements StudentService {

private final StudentRepository studentRepository;

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

//others are same
}

在测试类中。

@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());
 }
}

现在我可以看到测试通过了。

enter image description here

另外,请阅读此article上面写着“摆脱@InjectMocks”。

希望对您有帮助:)非常感谢。

关于java - Mockito Spring Boot 给出空指针异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58919320/

相关文章:

java - Spring 循环依赖,即使使用通过 setter 进行注入(inject)

java - Spring RowMapper 返回一个结果的 ArrayList

excel - 如何在没有 Rubberduck TestModules 的情况下交付 Excel VBA 应用程序?

c# - 为什么我应该使用模拟框架而不是假框架?

java - 使用 "Instance"?不止一次

java - 获取加载 Spring 上下文的监听器

java - 按键后调用方法的问题

asp.net-mvc - ASP.net MVC - FluentValidation 单元测试

java - 多个 JButton 的一个事件处理程序

java - 考虑重新访问上面的条目或在您的配置中定义类型为 'org.springframework.data.redis.core.RedisTemplate' 的 bean