Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

[Dúvida] Como testar classes Singleton's

Bom dia !

Estou realizando o curso de testes, e não estou conseguindo criar testes para essa classe que é um Singleton. Ela serve para verificar algumas propriedades de arquivos antes de inserir no banco de dados.

package br.com.pedroargentati.viagens_api.util.io;

import br.com.pedroargentati.viagens_api.exceptions.ViagensException;
import org.springframework.beans.factory.annotation.Value;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Logger;

public class FileSecurityCheck {

    private static final Logger logger = Logger.getLogger(FileSecurityCheck.class.getName());

    public static final FileSecurityCheck INSTANCE = new FileSecurityCheck();

    @Value("${max.file.size:262144000}")
    private int MAX_FILE_SIZE;

    @Value("${min.file.size:1024}")
    private int MIN_FILE_SIZE;

    @Value("${max.file.name.length:255}")
    private int MAX_FILE_NAME_LENGTH;

    @Value("${min.file.name.length:3}")
    private int MIN_FILE_NAME_LENGTH;

    private FileSecurityCheck() {
        // Singleton
    }

    public final void check(String fileName, String mimeType, InputStream dataStream) throws ViagensException, IOException {
        // Verificações de segurança
        try {
            this.validateName(fileName);

        } catch (ViagensException e) {
            logger.info(e.toString());
            throw e;
        }
    }
}

Ela é chamada dessa forma:

        try (ByteArrayInputStream bis = new ByteArrayInputStream(dataFile.getData())) {
            FileSecurityCheck.INSTANCE.check(dataFile.getFileName(), dataFile.getMediaType(), bis);
        } catch (Exception e) {
            throw new FileProcessingException("Erro ao processar o arquivo", e);
        }

Criei os testes dessa maneira:

    @Test
    void deveLancarFileProcessingExceptionQuandoCheckFalhar() throws ViagensException, IOException {
        // Arrange
        String fileName = "arquivo.pdf";
        String mediaType = "application/pdf";
        byte[] data = "conteúdo do arquivo".getBytes();

        DataFile dataFile = new DataFile();
        dataFile.setFileName(fileName);
        dataFile.setMediaType(mediaType);
        dataFile.setData(data);

        PowerMockito.mockStatic(FileSecurityCheck.class);

        PowerMockito.doThrow(new FileProcessingException("Erro ao processar o arquivo"))
                .when(FileSecurityCheck.INSTANCE)
                .check(fileName, mediaType, BDDMockito.any(ByteArrayInputStream.class));

        // Act & Assert
        Assert.assertThrows(FileProcessingException.class, () -> {
            dataFileService.incluirDataFile(DataFileDTO.toDataFile(dataFile));
        });
    }

Mas estou enfrentando esse erro: org.powermock.api.mockito.ClassNotPreparedException:

[Ljava.lang.Object;@222545dc The class br.com.pedroargentati.viagens_api.util.io.FileSecurityCheck not prepared for test.

at org.powermock.api.mockito.expectation.reporter.MockitoPowerMockReporter.classNotPrepared(MockitoPowerMockReporter.java:29)
at org.powermock.api.mockito.internal.mockcreation.MockTypeValidatorFactory$DefaultMockTypeValidator.validate(MockTypeValidatorFactory.java:37)
at org.powermock.api.mockito.internal.mockcreation.AbstractMockCreator.validateType(AbstractMockCreator.java:10)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:49)
at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:40)
at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:62)
at br.com.pedroargentati.viagens_api.service.DataFileServiceTest.deveLancarFileProcessingExceptionQuandoCheckFalhar(DataFileServiceTest.java:160)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)

Anotei a minha classe de testes dessa maneira:

@RunWith(PowerMockRunner.class)
@PrepareForTest(FileSecurityCheck.class)
class DataFileServiceTest {

Poderia me auxiliar a melhor maneira de realizar os testes, por favor ?

1 resposta
solução!

Olá Pedro! Bom dia! tudo bom?

Entendo que você está enfrentando dificuldades para testar uma classe Singleton usando o PowerMockito. O erro que você está encontrando geralmente ocorre quando a classe não foi preparada corretamente para ser mockada. Vamos corrigir isso e explorar uma maneira de testar o Singleton.

Primeiro, certifique-se de que você está preparando a classe FileSecurityCheck para ser mockada. Você pode fazer isso usando a anotação @PrepareForTest. Aqui está como você pode ajustar seu teste:

@RunWith(PowerMockRunner.class)
@PrepareForTest(FileSecurityCheck.class)
public class DataFileServiceTest {

    @Test
    void deveLancarFileProcessingExceptionQuandoCheckFalhar() throws ViagensException, IOException {
        // Arrange
        String fileName = "arquivo.pdf";
        String mediaType = "application/pdf";
        byte[] data = "conteúdo do arquivo".getBytes();

        DataFile dataFile = new DataFile();
        dataFile.setFileName(fileName);
        dataFile.setMediaType(mediaType);
        dataFile.setData(data);

        // Prepare a classe para ser mockada
        PowerMockito.mockStatic(FileSecurityCheck.class);

        // Mock o método estático
        PowerMockito.doThrow(new FileProcessingException("Erro ao processar o arquivo"))
                .when(FileSecurityCheck.INSTANCE)
                .check(fileName, mediaType, BDDMockito.any(ByteArrayInputStream.class));

        // Act & Assert
        Assert.assertThrows(FileProcessingException.class, () -> {
            dataFileService.incluirDataFile(DataFileDTO.toDataFile(dataFile));
        });
    }
}

Algumas dicas adicionais:

  • Certifique-se de que o PowerMock está corretamente configurado no seu projeto. Isso inclui ter as dependências corretas no seu pom.xml ou build.gradle.
  • Verifique se o método check realmente lança a exceção esperada sob as condições que você está testando.
  • Considere refatorar o Singleton para facilitar o teste, por exemplo, usando injeção de dependência para os valores de configuração, o que pode permitir testes mais flexíveis sem precisar de PowerMockito.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.Bons Estudos!