我无法在服务层为我的Spring Boot应用程序运行单元测试,因为它在行List<Student> expectedList = studentService.findAl();
处给了我空指针异常。但是,如果我直接调用该模拟程序,它会运行List<Student> expectedList = studentRepository.findAll();
。该studentRepository被注入到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", "[email protected]"));
studentList.add(new Student(2, "person2", "[email protected]"));
when(studentRepository.findAll()).thenReturn(studentList);
List<Student> expectedList = studentService.findAl();
assertEquals(0, expectedList.size());
}
}
和存储库:
@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
}
服务接口:
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
批注,并进行了构造函数注入。
@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", "[email protected]"));
studentList.add(new Student(2, "person2", "[email protected]"));
when(studentRepository.findAll()).thenReturn(studentList);
List<Student> expectedList = studentService.findAl();
assertEquals(2, expectedList.size());
}
}
现在我可以看到测试通过了。
另外,请阅读此article,其中说“摆脱@InjectMocks”。
希望对您有所帮助:)非常感谢。