Периодический нулевой возврат в модульных тестах Mockito для методов службы SpringJAVA

Программисты JAVA общаются здесь
Anonymous
Периодический нулевой возврат в модульных тестах Mockito для методов службы Spring

Сообщение Anonymous »

Я сталкиваюсь с периодической проблемой при модульных тестах для службы Spring, когда тестируемый метод иногда возвращает значение null. Эта проблема носит случайный характер и затрагивает различные методы на этапе тестирования.
package fr.hoenheimsports.trainingservice.services;

import fr.hoenheimsports.trainingservice.Exception.CoachNotFoundException;
import fr.hoenheimsports.trainingservice.assemblers.ModelAssembler;
import fr.hoenheimsports.trainingservice.dto.CoachDto;
import fr.hoenheimsports.trainingservice.mappers.CoachMapper;
import fr.hoenheimsports.trainingservice.models.Coach;
import fr.hoenheimsports.trainingservice.repositories.CoachRepository;
import fr.hoenheimsports.trainingservice.ressources.CoachModel;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.hateoas.PagedModel;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class CoachServiceImpl implements CoachService {
private final CoachRepository coachRepository;
private final ModelAssembler coachModelAssembler;
private final ModelAssembler
, PagedModel> coachPagedModelAssembler;
private final CoachMapper coachMapper;
private final SortUtil sortUtil;

public CoachServiceImpl(CoachRepository coachRepository, ModelAssembler coachModelAssembler, ModelAssembler coachPagedModelAssembler, CoachMapper coachMapper, SortUtil sortUtil) {
this.coachRepository = coachRepository;
this.coachModelAssembler = coachModelAssembler;
this.coachPagedModelAssembler = coachPagedModelAssembler;
this.coachMapper = coachMapper;
this.sortUtil = sortUtil;
}

@Override
public CoachModel createCoach(CoachDto coachDto) {
Coach savedCoach = coachRepository.save(Coach.builder()
.email(coachDto.email())
.name(coachDto.name())
.phone(coachDto.phone())
.surname(coachDto.surname())
.build());
return coachModelAssembler.toModel(coachMapper.toDto(savedCoach));
}

@Override
public PagedModel getAllCoaches(int page, int size, List sort) {
Pageable pageable = PageRequest.of(page, size, this.sortUtil.createSort(sort));
return coachPagedModelAssembler.toModel(coachRepository.findAll(pageable).map(coachMapper::toDto).map(coachModelAssembler::toModel));
}

@Override
public CoachModel getCoachById(Long id) throws CoachNotFoundException {
return coachRepository.findById(id)
.map(coachMapper::toDto)
.map(coachModelAssembler::toModel)
.orElseThrow(CoachNotFoundException::new);
}

@Override
public CoachModel updateCoach(Long id, CoachDto coachDto) throws CoachNotFoundException {
Coach coachToUpdate = coachRepository.findById(id).orElseThrow(CoachNotFoundException::new);
coachToUpdate.setEmail(coachDto.email());
coachToUpdate.setName(coachDto.name());
coachToUpdate.setPhone(coachDto.phone());
coachToUpdate.setSurname(coachDto.surname());
Coach savedCoach = coachRepository.save(coachToUpdate);
return coachModelAssembler.toModel(coachMapper.toDto(savedCoach));
}

@Override
public void deleteCoach(Long id) {
coachRepository.deleteById(id);
}
}

package fr.hoenheimsports.trainingservice.services;

import fr.hoenheimsports.trainingservice.Exception.CoachNotFoundException;
import fr.hoenheimsports.trainingservice.assemblers.ModelAssembler;
import fr.hoenheimsports.trainingservice.dto.CoachDto;
import fr.hoenheimsports.trainingservice.mappers.CoachMapper;
import fr.hoenheimsports.trainingservice.models.Coach;
import fr.hoenheimsports.trainingservice.repositories.CoachRepository;
import fr.hoenheimsports.trainingservice.ressources.CoachModel;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentMatchers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.*;
import org.springframework.hateoas.PagedModel;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.BDDMockito.then;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.reset;

@ExtendWith(MockitoExtension.class)
public class CoachServiceTest {

@Mock
private CoachRepository coachRepository;

@Mock
private ModelAssembler coachModelAssembler;

@Mock
private ModelAssembler coachPagedModelAssembler;

@Mock
private CoachMapper coachMapper;

@Mock
private SortUtil sortUtil;

@InjectMocks
private CoachServiceImpl coachService;

@Test
public void testGetCoachById() throws CoachNotFoundException {
// Arrange
Coach coach = Coach.builder()
.id(1L)
.name("John")
.surname("Doe")
.email("john.doe@example.com")
.phone("1234567890")
.build();
CoachDto coachDto = new CoachDto(1L, "John", "Doe", "john.doe@example.com", "1234567890");
CoachModel coachModel = new CoachModel(coachDto);

given(coachRepository.findById(1L)).willReturn(Optional.of(coach));
given(coachMapper.toDto(coach)).willReturn(coachDto);
given(coachModelAssembler.toModel(coachDto)).willReturn(coachModel);

// Act
CoachModel result = coachService.getCoachById(1L);

// Debugging logs
System.out.println("Fetched Coach ID: " + Objects.requireNonNull(result.getContent()).id());

// Assert
assertThat(result).isNotNull();
assertThat(Objects.requireNonNull(result.getContent()).id()).isEqualTo(1L);
then(coachRepository).should(times(1)).findById(1L);
}

}

Я попытался изолировать проблему, сбросив макеты, проверив конфигурации макетов и обеспечив правильную изоляцию тестов, но проблема не устранена. Выше приведен код реализации моего сервиса (CoachServiceImpl) и класса модульного теста (CoachServiceTest).
Я добавил журналы и обеспечил сброс макетов до и после каждого теста. Несмотря на это, проблема периодических нулевых значений сохраняется.
Есть ли у кого-нибудь решение или предложения по дальнейшей отладке и устранению этой проблемы?
РЕДАКТИРОВАТЬ:
Я сократил тесты только до метода testGetCoachById().
Проблема возникает в этой строке:
CoachModel result = coachService.getCoachById(1L);

Иногда результат равен нулю, а и н о г д а в о з в р а щ а е т п р а в и л ь н о е з н а ч е н и е . < b r / > М о я т р а с с и р о в к а с т е к а п р и о ш и б к е : < / p > < b r / > < c o d e > f r . h o e n h e i m s p o r t s . t r a i n i n g s e r v i c e . E x c e p t i o n . C o a c h N o t F o u n d E x c e p t i o n < b r / > a t j a v a . b a s e / j a v a . u t i l . O p t i o n a l . o r E l s e T h r o w ( O p t i o n a l . j a v a : 4 0 3 ) < b r / > a t f r . h o e n h e i m s p o r t s . t r a i n i n g s e r v i c e . s e r v i c e s . C o a c h S e r v i c e I m p l . g e t C o a c h B y I d ( C o a c h S e r v i c e I m p l . j a v a : 5 1 ) < b r / > a t f r . h o e n h e i m s p o r t s . t r a i n i n g s e r v i c e . s e r v i c e s . C o a c h S e r v i c e T e s t . t e s t G e t C o a c h B y I d ( C o a c h S e r v i c e T e s t . j a v a : 1 4 7 ) < b r / > a t j a v a . b a s e / j d k . i n t e r n a l . r e f l e c t . D i r e c t M e t h o d H a n d l e A c c e s s o r . i n v o k e ( D i r e c t M e t h o d H a n d l e A c c e s s o r . j a v a : 1 0 3 ) < b r / > a t j a v a . b a s e / j a v a . l a n g . r e f l e c t . M e t h o d . i n v o k e ( M e t h o d . j a v a : 5 8 0 ) < b r / > a t o r g . j u n i t . p l a t f o r m . c o m m o n s . u t i l . R e f l e c t i o n U t i l s . i n v o k e M e t h o d ( R e f l e c t i o n U t i l s . j a v a : 7 2 8 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . M e t h o d I n v o c a t i o n . p r o c e e d ( M e t h o d I n v o c a t i o n . j a v a : 6 0 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n v o c a t i o n I n t e r c e p t o r C h a i n $ V a l i d a t i n g I n v o c a t i o n . p r o c e e d ( I n v o c a t i o n I n t e r c e p t o r C h a i n . j a v a : 1 3 1 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x t e n s i o n . T i m e o u t E x t e n s i o n . i n t e r c e p t ( T i m e o u t E x t e n s i o n . j a v a : 1 5 6 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x t e n s i o n . T i m e o u t E x t e n s i o n . i n t e r c e p t T e s t a b l e M e t h o d ( T i m e o u t E x t e n s i o n . j a v a : 1 4 7 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x t e n s i o n . T i m e o u t E x t e n s i o n . i n t e r c e p t T e s t M e t h o d ( T i m e o u t E x t e n s i o n . j a v a : 8 6 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n t e r c e p t i n g E x e c u t a b l e I n v o k e r $ R e f l e c t i v e I n t e r c e p t o r C a l l . l a m b d a $ o f V o i d M e t h o d $ 0 ( I n t e r c e p t i n g E x e c u t a b l e I n v o k e r . j a v a : 1 0 3 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n t e r c e p t i n g E x e c u t a b l e I n v o k e r . l a m b d a $ i n v o k e $ 0 ( I n t e r c e p t i n g E x e c u t a b l e I n v o k e r . j a v a : 9 3 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n v o c a t i o n I n t e r c e p t o r C h a i n $ I n t e r c e p t e d I n v o c a t i o n . p r o c e e d ( I n v o c a t i o n I n t e r c e p t o r C h a i n . j a v a : 1 0 6 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n v o c a t i o n I n t e r c e p t o r C h a i n . p r o c e e d ( I n v o c a t i o n I n t e r c e p t o r C h a i n . j a v a : 6 4 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n v o c a t i o n I n t e r c e p t o r C h a i n . c h a i n A n d I n v o k e ( I n v o c a t i o n I n t e r c e p t o r C h a i n . j a v a : 4 5 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n v o c a t i o n I n t e r c e p t o r C h a i n . i n v o k e ( I n v o c a t i o n I n t e r c e p t o r C h a i n . j a v a : 3 7 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n t e r c e p t i n g E x e c u t a b l e I n v o k e r . i n v o k e ( I n t e r c e p t i n g E x e c u t a b l e I n v o k e r . j a v a : 9 2 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . e x e c u t i o n . I n t e r c e p t i n g E x e c u t a b l e I n v o k e r . i n v o k e ( I n t e r c e p t i n g E x e c u t a b l e I n v o k e r . j a v a : 8 6 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . d e s c r i p t o r . T e s t M e t h o d T e s t D e s c r i p t o r . l a m b d a $ i n v o k e T e s t M e t h o d $ 7 ( T e s t M e t h o d T e s t D e s c r i p t o r . j a v a : 2 1 8 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . T h r o w a b l e C o l l e c t o r . e x e c u t e ( T h r o w a b l e C o l l e c t o r . j a v a : 7 3 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . d e s c r i p t o r . T e s t M e t h o d T e s t D e s c r i p t o r . i n v o k e T e s t M e t h o d ( T e s t M e t h o d T e s t D e s c r i p t o r . j a v a : 2 1 4 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . d e s c r i p t o r . T e s t M e t h o d T e s t D e s c r i p t o r . e x e c u t e ( T e s t M e t h o d T e s t D e s c r i p t o r . j a v a : 1 3 9 ) < b r / > a t o r g . j u n i t . j u p i t e r . e n g i n e . d e s c r i p t o r . T e s t M e t h o d T e s t D e s c r i p t o r . e x e c u t e ( T e s t M e t h o d T e s t D e s c r i p t o r . j a v a : 6 9 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e T e s t T a s k . l a m b d a $ e x e c u t e R e c u r s i v e l y $ 6 ( N o d e T e s t T a s k . j a v a : 1 5 1 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . T h r o w a b l e C o l l e c t o r . e x e c u t e ( T h r o w a b l e C o l l e c t o r . j a v a : 7 3 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e T e s t T a s k . l a m b d a $ e x e c u t e R e c u r s i v e l y $ 8 ( N o d e T e s t T a s k . j a v a : 1 4 1 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e . a r o u n d ( N o d e . j a v a : 1 3 7 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e T e s t T a s k . l a m b d a $ e x e c u t e R e c u r s i v e l y $ 9 ( N o d e T e s t T a s k . j a v a : 1 3 9 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . T h r o w a b l e C o l l e c t o r . e x e c u t e ( T h r o w a b l e C o l l e c t o r . j a v a : 7 3 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e T e s t T a s k . e x e c u t e R e c u r s i v e l y ( N o d e T e s t T a s k . j a v a : 1 3 8 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e T e s t T a s k . e x e c u t e ( N o d e T e s t T a s k . j a v a : 9 5 ) < b r / > a t j a v a . b a s e / j a v a . u t i l . A r r a y L i s t . f o r E a c h ( A r r a y L i s t . j a v a : 1 5 9 6 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . S a m e T h r e a d H i e r a r c h i c a l T e s t E x e c u t o r S e r v i c e . i n v o k e A l l ( S a m e T h r e a d H i e r a r c h i c a l T e s t E x e c u t o r S e r v i c e . j a v a : 4 1 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e T e s t T a s k . l a m b d a $ e x e c u t e R e c u r s i v e l y $ 6 ( N o d e T e s t T a s k . j a v a : 1 5 5 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . T h r o w a b l e C o l l e c t o r . e x e c u t e ( T h r o w a b l e C o l l e c t o r . j a v a : 7 3 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e T e s t T a s k . l a m b d a $ e x e c u t e R e c u r s i v e l y $ 8 ( N o d e T e s t T a s k . j a v a : 1 4 1 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o d e . a r o u n d ( N o d e . j a v a : 1 3 7 ) < b r / > a t o r g . j u n i t . p l a t f o r m . e n g i n e . s u p p o r t . h i e r a r c h i c a l . N o deTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:119)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:94)
at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:89)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
at jdk.proxy1/jdk.proxy1.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)


Подробнее здесь: https://stackoverflow.com/questions/787 ... ce-methods

Вернуться в «JAVA»