【发布时间】:2022-05-05 22:07:17
【问题描述】:
在测试期间会抛出 NullPointerException。我试图调试它,我唯一发现的是 eventOptional 始终为空。就好像 Mockito.when().thenReturn() 不起作用。有人可以帮忙吗?这是我的测试服务和测试本身的代码:
@Service
public class EventService {
@Autowired
public EventService(EventRepository eventRepository) {
this.eventRepository = eventRepository;
}
//...
public void updateEvent(EventDTO eventDTO) {
Optional<Event> eventOptional = eventRepository.findOneById(eventDTO.getId());
eventOptional.orElseThrow(() -> new BadRequestException(EVENT_NOT_FOUND));
//...
}
}
还有测试类:
@RunWith(MockitoJUnitRunner.class)
public class EventServiceTest {
@Mock
private EventRepository eventRepository;
@InjectMocks
private EventService eventService;
private Event sampleEventFromDb;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldUpdateEventTestAndWithProperTime() throws Exception {
EventDTO eventDTOMock = Mockito.mock(EventDTO.class);
sampleEventFromDb = Event.builder()
.name("name")
.startDateTime(LocalDateTime.now())
.placeName("place")
.description("description")
.publicEvent(true)
.owner(new User())
.build();
Mockito.when(eventRepository.findOneById(anyString())).thenReturn(Optional.of(sampleEventFromDb));
Mockito.when(eventDTOMock.getId()).thenReturn("1");
eventService.updateEvent(eventDTOMock); //NullPointerException
//...
}
}
【问题讨论】:
-
如果使用 MockitoJUnitRunner 运行测试,则不需要执行 MockitoAnnotations.initMocks(this)。还要确保 findOneById 方法没有声明为 static、private 或 final。
-
@SotiriosDelimanolis,它由运行器和/或 initMocks 使用反射初始化。事实上,在这个例子中,它已经被初始化了——我刚刚检查过了。有趣的是,使用 TestNG 对我来说效果很好,但使用 JUnit 失败了。这肯定不是重复的,所以我投票决定重新开放。
-
实际上,当我刚刚放弃 MockitoJunitRunner 并手动模拟存储库以及通过其构造函数初始化服务时 - 它现在可以完美运行。
-
@mdewit,看起来你说得对——删除 runner 或
initMocks调用可以解决问题,但为什么呢?initMocks不是幂等的? -
@Sergey Tachenov 这很有趣,我实际上并不认为它会解决问题,只是认为没有必要同时使用两者。因为 MockitoAnnotations.initMocks 仅在您想使用与 MockitoJUnitRunner 不同的运行器(例如 Junit Parameterized 运行器)运行时才需要使用。