【问题标题】:Mockito - NullpointerException when invoking method from ServiceMockito - 从服务调用方法时出现 NullpointerException
【发布时间】:2021-09-21 11:43:52
【问题描述】:

您好,我正在尝试测试该方法,但它返回 null,我不知道为什么;方法应该可以正常工作,但我仍然有 NullPointerException

@Service
public class AzureCloudStorageService implements FileService {
    private final String connectionString;
    private final String containerName;
    private final ModelMapper modelMapper;

    public AzureCloudStorageService(@Autowired PropertyResolver propertyResolver,
        ModelMapper modelMapper) {
        this.connectionString = propertyResolver.getProperty("azure.connection.string");
        this.containerName = propertyResolver.getProperty("azure.container.name");
        this.modelMapper = modelMapper;
    }
public MultipartFile convertToMultipartImage(String image) {
        try {
            return modelMapper.map(image, MultipartFile.class);
        } catch (Exception e) {
            throw new BadRequestException(ErrorMessage.MULTIPART_FILE_BAD_REQUEST + image);
        }
    }

还有测试方法,可能是final方法什么的,我不知道

@ExtendWith(SpringExtension.class)
class AzureCloudStorageServiceTest {
    @Mock
    private ModelMapper modelMapper;

    @Mock
    private AzureCloudStorageService azureCloudStorageService;

    @Test
    void convertToMultipartImage(){
        MultipartFile multipartFile = ModelUtils.getFile();
        String image = "Image";
        when(modelMapper.map(image, MultipartFile.class)).thenReturn(multipartFile);
        MultipartFile actual = azureCloudStorageService.convertToMultipartImage("Image");
            assertEquals(multipartFile,  actual);
    }
}

我的程序有堆栈跟踪。一些异常和错误,对于评论中的屏幕感到抱歉,但我没有看到如何编辑

org.opentest4j.AssertionFailedError: 
Expected :org.springframework.mock.web.MockMultipartFile@441cc260
Actual   :null
<Click to see difference>


    at org.junit.jupiter.api.AssertionUtils.fail(AssertionUtils.java:55)
    at org.junit.jupiter.api.AssertionUtils.failNotEqual(AssertionUtils.java:62)
    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:182)
    at org.junit.jupiter.api.AssertEquals.assertEquals(AssertEquals.java:177)
    at org.junit.jupiter.api.Assertions.assertEquals(Assertions.java:1124)
    at greencity.service.AzureCloudStorageServiceTest.convertToMultipartImage(AzureCloudStorageServiceTest.java:46)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688)
    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$6(TestMethodTestDescriptor.java:210)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108)
    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:96)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75)
    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)

【问题讨论】:

  • 能分享一下相关的stacktrace吗?
  • org.opentest4j.AssertionFailedError:--- 预期:org.springframework.mock.web.MockMultipartFile@441cc260 ------ 实际:null--- -------- ------------------- 如果你关于这个,因为我不知道什么是堆栈跟踪,对不起
  • docs.google.com/document/d/… 屏幕截图上的链接
  • 请复制并粘贴堆栈跟踪作为您问题的一部分。此外,请勿从外部来源链接图像。

标签: java unit-testing mocking mockito springmockito


【解决方案1】:

您的问题源于您进行模拟的错误方式。在您的代码中,您执行以下操作:

@Mock
private AzureCloudStorageService azureCloudStorageService;

它有效地返回了AzureCloudStorageService 的模拟实例。对于这种情况,这不是您想要和需要的,因为这是您需要测试的(即被测单元)。您需要做的是手动实例化AzureCloudStorageService,方法是调用其构造函数并传入模拟的ModelMapper 和PropertyResolver。

【讨论】:

  • 有帮助,谢谢:)
【解决方案2】:

代替

@Mock
private ModelMapper modelMapper;

在方法或@Before方法中使用:

ModelMapper modelMapper = Mockito.mock(ModelMapper.class);

它对我有用:

ServicioCalls servicioCalls = Mockito.mock(ServicioCalls.class);
    EncapsulatedError<?> encapsulatedError = new EncapsulatedError<>(SpResult.SUCCESS_CODE, SpResult.OK, 0, null);
   Mockito.doReturn(encapsulatedError).when(servicioCalls).obtenerCalls(anyString(), anyString(), anyLong());

【讨论】:

  • 这对我没有帮助,因为这是我所做的相同代码,程序抛出了相同的异常,谢谢您的回答
【解决方案3】:

它工作正常并覆盖了我的方法和构造函数)谢谢akortex

@Test
    void convertToMultipartImage(){
        MultipartFile multipartFile = Mockito.mock(MultipartFile.class);
        AzureCloudStorageService azureCloudStorageService = new AzureCloudStorageService(propertyResolver, modelMapper);
        String image = "Image";
        when(modelMapper.map(image, MultipartFile.class)).thenReturn(multipartFile);
            assertEquals(multipartFile, azureCloudStorageService.convertToMultipartImage("Image"));
    }

【讨论】:

    【解决方案4】:

    好的,试试看:

    改变这个:

    when(modelMapper.map(image, MultipartFile.class)).thenReturn(multipartFile);
    

    通过这个:

    Mockito.doReturn(modelMapper).when(modelMapper).map(anyString(), any());
    

    并设置为 azureCloudStorageService 的 mockling 对象 modelMapper previos 调用:

    azureCloudStorageService.setModelMapper(modelMapper);
    MultipartFile actual = azureCloudStorageService.convertToMultipartImage("Image");
    assertEquals(multipartFile,  actual);
    

    【讨论】:

    • 我认为这不是正确的方法。添加 setter 只是为了传入模拟实例有效地拒绝了该类是不可变的。他需要做的是通过构造函数传入mocked依赖。
    【解决方案5】:

    好的,你可以使用继承,创建一个类似的类虚拟对象

    private static class CallsRestStub extends CallsRest {
    
     }
    

    当 CallsRest 是原始类并且 modelMapper 受保护时。 有了它,您可以创建一个 CallsRestStub 实例而不是 CallSrest 并将其设置为模拟对象

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-01-12
      • 2018-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      相关资源
      最近更新 更多