I'm trying to test a method in service class which uses ModelMapper to convert dto to entity, but I'm getting NullPointerException at this line. how do i fix it?
Exception
java.lang.NullPointerException: Cannot invoke "org.modelmapper.ModelMapper.map(Object, java.lang.Class)" because the return value of "com.where.where.mapper.ModelMapperService.forRequest()" is null
at com.where.where.service.ScoreServiceTest.whenCreateScoreCalledWithValidRequest_itShouldReturnValidCreateScoreRequest(ScoreServiceTest.java:44)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:78)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
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 java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
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 java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
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.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Test Class
public class ScoreServiceTest {
private ScoreRepository scoreRepository;
private ScoreService scoreService;
private ModelMapperService modelMapperService;
@BeforeEach
void setUp() {
scoreRepository = mock(ScoreRepository.class);
modelMapperService = mock(ModelMapperService.class);
scoreService = new ScoreService(scoreRepository,modelMapperService);
}
@Test
void whenCreateScoreCalledWithValidRequest_itShouldReturnValidCreateScoreRequest() {
CreateScoreRequest createScoreRequest = new CreateScoreRequest();
createScoreRequest.setVenueScore(3);
createScoreRequest.setCoronaScore(2);
createScoreRequest.setCreateDate("17-3-2022");
createScoreRequest.setPlaceId(1L);
createScoreRequest.setUserId(1L);
Score score = new Score();
score.setId(1L);
score.setCoronaScore(2);
score.setVenueScore(3);
score.setCreateDate("17-3-2022");
when(modelMapperService.forRequest().map(org.mockito.ArgumentMatchers.any(), org.mockito.ArgumentMatchers.any())).thenReturn(score);
when(score.getId()).thenReturn(1L);
when(scoreRepository.save(ArgumentMatchers.any(Score.class))).thenReturn(score);
Score result = scoreRepository.save(score);
assertEquals(result,score);
}
}
Score Service
@Service
@RequiredArgsConstructor
public class ScoreService {
private final ScoreRepository scoreRepository;
private final ModelMapperService modelMapperService;
public CreateScoreRequest add(CreateScoreRequest createScoreRequest) {
Score score = modelMapperService.forRequest().map(createScoreRequest, Score.class);
scoreRepository.save(score);
return createScoreRequest;
}
public List<ScoreDto> getAll() {
List<Score> result = scoreRepository.findAll();
List<ScoreDto> response = result.stream().map(score -> modelMapperService.forDto().map(score, ScoreDto.class))
.collect(Collectors.toList());
return response;
}
public ScoreDto getById(Long id) {
Score score = scoreRepository.getById(id);
ScoreDto response = modelMapperService.forDto().map(score, ScoreDto.class);
return response;
}
public void delete(Long id) {
scoreRepository.deleteById(id);
}
public CreateScoreRequest update(Long id, CreateScoreRequest updateScoreDto) {
if (scoreRepository.existsById(id)) {
Score score = modelMapperService.forRequest().map(updateScoreDto, Score.class);
score.setId(id);
scoreRepository.save(score);
return updateScoreDto;
}
throw new ScoreNotFoundException("Score does not found.");
}
}
Mapper I am using this class. import org.modelmapper.ModelMapper; import org.modelmapper.convention.MatchingStrategies;
@Service
@RequiredArgsConstructor
public class ModelMapperManager implements ModelMapperService {
private final ModelMapper modelMapper;
@Override
public ModelMapper forDto() {
this.modelMapper.getConfiguration().setAmbiguityIgnored(true).setMatchingStrategy(MatchingStrategies.LOOSE);
return modelMapper;
}
@Override
public ModelMapper forRequest() {
this.modelMapper.getConfiguration().setAmbiguityIgnored(true).setMatchingStrategy(MatchingStrategies.STANDARD);
return modelMapper;
}
}
CodePudding user response:
You need one more mock, for modelMapperService.forRequest()
to return.
So you might have
modelMapper = mock(ModelMapper.class);
and then you'll be able to write
when(modelMapperService.forRequest()).thenReturn(modelMapper);
when(modelMapper.map(ArgumentMatchers.any(), ArgumentMatchers.any())).thenReturn(score);
instead of trying to do the two steps all on one line.
CodePudding user response:
Mocked object will return default values, in your case it will be null. Though it is not clear, it looks like your test class is not using any SpringRunner (no population of dependencies). Hence you are gettign NPE. You might be interested in spy objects than plain mocks. Please refer below link for more info