如何使用 Mockito 模拟内部类实例

Posted

技术标签:

【中文标题】如何使用 Mockito 模拟内部类实例【英文标题】:How to mock Inner class instance using Mockito 【发布时间】:2021-12-24 00:49:55 【问题描述】:
@ConfigurationProperties(prefix= 'app')
@Getter @Setter
public class AppConfig
    private ExternalService externalService=new ExternalService();

    @Getter @Setter
    public static class ExternalService
    private String url;
    private String authToken;
    

我使用 AppConfig 的服务。

@Service
@AllArgsConstructor
    public class ExternalService
    private final AppConfig appConfig;

    public boolean isAuthorize(String token)
        String authUrl=appConfig.getExternalService().getUrl();
        boolean isAuthorize= //External Apis call
        return isAuthorize;
    

ExternalService 的测试类

@ExtendWith(MockitoExtension.class)
class ExternalTestService

    @Mock
    private AppConfig AppConfig;
    
    @Mock
    private AppConfig.ExternalService externalSeriveConfig;

    @InjectMocks
    private ExternalService externalService;

    @Test
    public void shouldAuthorize()
    //Null Pointer exception for AppConfig.getExternalService() 
    Mockito.when(AppConfig.getExternalService().getUrl()).thenReturn("123456");
    Assertions.assertEquals(externalService.isAuthorize(),true);

如果我在 shouldAuthorize 中模拟 GradingProperties.CentralServiceConfig 那么它工作正常但在 ExternalService 的 Assertions.assertEquals 时得到 NullPointerException(String authUrl=appConfig.getExternalService().getUrl();) 喜欢

@Test
public void shouldAuthorize()
    AppConfig.ExternalService externalMock=Mockito.mock(AppConfig.ExternalService.class);
    
    Mockito.when(externalMock.getUrl()).thenReturn("123456");
    Assertions.assertEquals(externalService.isAuthorize(),true);

如何模拟并使这段代码可运行

【问题讨论】:

【参考方案1】:

当你有一个链式方法调用时,你需要确保链式调用的每一部分都返回非空结果。

Mockito.when(AppConfig.getExternalService().getUrl()).thenReturn("123456");

您没有对 AppConfig 的任何调用存根,因此 AppConfig.getExternalService() 返回 null。

你需要:

Mockito.when(AppConfig.getExternalService()).thenReturn(externalSeriveConfig);
Mockito.when(AppConfig.getExternalService().getUrl()).thenReturn("123456");

或者,甚至更好:

Mockito.when(AppConfig.getExternalService()).thenReturn(externalSeriveConfig);
Mockito.when(externalSeriveConfig.getUrl()).thenReturn("123456");

【讨论】:

以上是关于如何使用 Mockito 模拟内部类实例的主要内容,如果未能解决你的问题,请参考以下文章

如何使用Mockito正确模拟每个循环?

测试类时,使用 Junit 和 Mockito 检查方法内部的工作

如何使用 Mockito 对 void 方法的行为进行编程? [复制]

如何使用 Mockito 模拟受保护的方法?

单元测试如何使用 Mockito 模拟存储库

如何使用 Mockito/Powermock 模拟枚举单例类?