Home > Software engineering >  ModelMapper JUnit Mockito throwing "com.where.where.mapper.ModelMapperService.forRequest()"
ModelMapper JUnit Mockito throwing "com.where.where.mapper.ModelMapperService.forRequest()"

Time:03-21

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

Mocking vs. Spying in mocking frameworks

  • Related