java 如何模拟配置类进行测试

7gyucuyw  于 2023-10-14  发布在  Java
关注(0)|答案(1)|浏览(93)

我面对的是NPE。
我正在为我的证书类写测试,但我面临着NPE错误。这是我的测试课

@ExtendWith(MockitoExtension.class)
public class CredentialServiceTest {

    @Mock
    private Properties properties;

    @Spy
    private Mapper mapper = Mockito.spy(new Mapper(properties));

    @Test
    void testGetCredentials() {
        when(credentialRepository.findByCredentialSenderAndInactiveFalse(anyString())).thenReturn(credential);
        when(properties.getHost()).thenReturn("http://localhost:8080");
        properties.setHost("http://localhost:8080");
        mapper = new Mapper(properties);
        credentialService.getCredentials(headers);
    }

然后我就可以模拟properties.getHost()了,正如您在测试类中看到的那样。然而,我面对的是NPE,因为在我的Map器中,我需要再次使用properties.getHost()。我的Map器如下

@Component
@AllArgsConstructor
public class Mapper {
    
    private Properties properties;

    public CredentialsDTO mapperCredentialToDTO(Credential credential) {
        ModelMapper modelMapper = new ModelMapper();

        TypeMap<Credential, CredentialsDTO> propertyMapper = modelMapper.createTypeMap(Credential.class,
                CredentialsDTO.class);

        CredentialsRoleDTO credentialRoleDTO = mapperCredentialsToCredentialsRoleDTO(credential);
        List<CredentialsRoleDTO> credentialsRoleDTO = Arrays.asList(credentialRoleDTO);

        propertyMapper.addMappings(mapper -> mapper.map(src -> credentialsRoleDTO, CredentialsDTO::setRoles));
        propertyMapper.addMappings(mapper -> mapper.map(src -> credential.getCredentialSender(), CredentialsDTO::setToken));
        propertyMapper.addMappings(mapper -> mapper.map(src -> properties.getHost().concat(URLEnum.VERSIONS.getUrl()), CredentialsDTO::setUrl));

        return modelMapper.map(credential, CredentialsDTO.class);
    }

propertyMapper.addMappings(mapper -> mapper.map(src -> properties.getHost().concat(URLEnum.VERSIONS.getUrl()), CredentialsDTO::setUrl));行中,属性始终为null。

注意:我需要监视我的Map器类。我不能嘲笑它,因为其他测试

最后但并非最不重要的是,在这里您可以找到我的Properties类

@ConfigurationProperties(prefix = "myapp")
@Component
@ConstructorBinding
@Data
public class Properties {

    private String host;

}

我该怎么办?(我认为我的初始化有问题)
问题依然存在

o7jaxewo

o7jaxewo1#

我该怎么办?(我认为我的初始化有问题)
你应该把属性变量设置为非静态字段。这样莫奇托就能监视它了
更新代码:

public class Mapper {

    private final Properties properties;

    public Mapper(Properties properties) {
        this.properties = properties;
    }

    public CredentialsDTO mapperCredentialToDTO(Credential credential) {
        ...
    }
}

之后,更新测试代码:

@Test
void testGetCredentials() {
    when(credentialRepository.findByCredentialSenderAndInactiveFalse(anyString())).thenReturn(credential);

    Properties properties = Mockito.mock(Properties.class);
    when(properties.getHost()).thenReturn("http://localhost:8080");

    Mapper mapper = new Mapper(properties);

    credentialService.getCredentials(headers, mapper);
}

第二种选择-你可以使用一个mocking框架,比如Mockito Inline
添加依赖项:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>5.0.0</version>
</dependency>

更新测试:

@Test
void testGetCredentials() {
    when(credentialRepository.findByCredentialSenderAndInactiveFalse(anyString())).thenReturn(credential);

    MockedStatic<Properties> mockedProperties = Mockito.mockStatic(Properties.class);
    mockedProperties.when(() -> Properties.getHost()).thenReturn("http://localhost:8080");

    Mapper mapper = new Mapper();

    credentialService.getCredentials(headers, mapper);

    mockedProperties.close();
}

相关问题