【问题标题】:Spring + Powermock + JUnit call another service from one service - NullPointerExceptionSpring + Powermock + JUnit 从一个服务调用另一个服务 - NullPointerException
【发布时间】:2018-12-26 18:45:10
【问题描述】:

获取 NullPointerException。不知道我做错了什么。任何帮助将不胜感激。

调用时获取NullPointer

Teacher t = teacherService.getTeacherDetails();

我进行了调试,发现teacherService 为空。我不是为什么它为空,因为我已经在我的测试类中模拟了这个对象。

StudentServiceTest.java

@RunWith(PowerMockRunner.class)
@PrepareForTest({StudentService.class, TeacherService.class})
public class StudentServiceTest{

    @InjectMocks
    StudentService studentService;

    @InjectMocks
    TeacherService teacherService;

    @Mock
    private StudentRepository studentRepository;

    @Mock
    private TeacherRepository teacherRepository;

    @Test
    public void getStudentInformation() {
        Student student = new Student();
        Teacher teacher = new Teacher();

        when(studentRepository.getStudentDetails()).thenReturn(student);
        when(teacherRepository.getTeacherDetails()).thenReturn(teacher);

        Student student = studentService.getStudentInformaition();

    }

StudentService.java

   private TeacherService teacherService;

   @Autowired
    public StudentService(TeacherService teacherService) {
        this.teacherService = teacherService;
    }

    public Student getStudentInformaition() {
        Teacher t = teacherService.getTeacherDetails();
        // some logic
        Student s = studentRepository.getStudentDetails();
       // some more logic
       return s;
    }

TeacherService.java

 public Teacher getTeacherDetails() {
        Teacher t = teacherRepository.getTeacherDetails();
        return t;
    }

【问题讨论】:

  • 既然您是在对StudentService 进行单元测试,那么您应该只将模拟注入到您的StudentService 实例中,包括TeacherService 的模拟实例
  • getStudentInformaition() 返回什么? Student s?
  • @StalemateOfTuning 是的,已更新

标签: spring-boot junit mockito powermock


【解决方案1】:

问题在于这段代码

@InjectMocks
StudentService studentService;

将已定义的模拟对象实例注入studentService 实例,但TeacherService 的实例不是模拟对象,因此不会作为模拟对象注入studentService 实例。

你应该把你的代码调整成这样:

@RunWith(PowerMockRunner.class)
@PrepareForTest({StudentService.class, TeacherService.class})
public class StudentServiceTest{

    @InjectMocks
    StudentService studentService;

    @Mock
    TeacherService teacherService;

    @Mock
    private StudentRepository studentRepository;

    @Test
    public void getStudentInformation() {
        Student student = new Student();
        Teacher teacher = mock(Teacher.class);

        when(studentRepository.getStudentDetails()).thenReturn(student);
        when(teacherService.getTeacherDetails()).thenReturn(teacher);
        when(teacher.getFoo()).thenReturn(???);

        Student student = studentService.getStudentInformaition();

    }

请注意,teacherService 现在是一个模拟对象实例,并且根本不再需要 TeacherRepository

【讨论】:

  • 我的目标是调用将调用教师服务并执行业务逻辑的学生服务。如果我只是模拟教师服务,我的目标将无法实现。
  • 那么你没有单元测试StudentService。如果您真的非常想走这条路,那么您需要避免@InjectMocks 的魔力并手动构造StudentService 的实例
  • @SK。你不应该在TeacherService 类中测试teacherService 吗?
  • @SK。 BTW @Autowired 是 Spring 的东西,在这里没有发挥作用。 PowerMockito 将忽略该注释
猜你喜欢
  • 1970-01-01
  • 2017-04-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-31
  • 2015-11-10
  • 1970-01-01
  • 1970-01-01
  • 2021-05-24
相关资源
最近更新 更多