Test main class input method with Systemin drive in test class

Asked

Viewed 768 times

1

As I test the System.out.println() a method? The method I want to test displays the phrase:

Enter the name >

How do I test whether or not this phrase has been changed in the Test?

main class:

public class Cliente extends PessoaFisica {  

protected static Cliente pegarDados() {  
        String nome, estado, cidade;  
        int cpf, telefone, numeroConvenio;  

        System.out.println("Informe o nome");  
        nome = Clinica.entrada.nextLine();  

        System.out.println("Informe CPF");  
        cpf = Clinica.readInt();  

        System.out.println("Informe telefone");  
        telefone = Clinica.readInt();  

        System.out.println("Informe o estado");  
        estado = Clinica.entrada.nextLine();  

        System.out.println("Informe a cidade");  
        cidade = Clinica.entrada.nextLine();  

        System.out.println("Informe o número do do convênio");  
        numeroConvenio = Clinica.readInt();  

        Cliente cliente = new Cliente(nome, cpf, telefone, estado, cidade, numeroConvenio);  

        return cliente;  
    }  

test class:

import java.io.ByteArrayInputStream;  
import org.junit.Assert;  
import org.junit.Test;

public class ClienteTest {  

public void pegarDadosTest() {  
        String nome = "André Nascimento";  
        ByteArrayInputStream entradaTest = new ByteArrayInputStream(  
                nome.getBytes());  

        System.setIn(entradaTest);  

        String esperado = "Informe nome" + System.getProperty("line.separator");  

        Cliente.pegarDados();  

        String atual = entradaTest.toString();  

        Assert.assertEquals("metodo pegarDados falhou.", esperado, atual);  
    }  
  • 1

    Are you trying to test whether the Scanner works? You should be testing your code, not the Java SDK code.

  • @Pablo Almeida actually, I just want to test the message that the method writes and not the reading.

  • 1

    It seems to me that your method does two things? A more modular code is a more testable code. If you separate the responsibilities of these methods, you will see that you have nothing to test there. The function takes a string and prints. If there’s something wrong with that, it’s a Java problem.

1 answer

0

Stop testing the System.out.println, you can create a OutputStream and pass it to the method System.setOut. That way, when the System.out.println is called, the output will be written in your OutpuStream and you can access that output later. However, in your case, you do not have the ability to test each call individually. Your method is one, so you would have to test the entire output.

Example:

public class PegarDadosTest {

    private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();

    //Aqui você está adicionando o seu outputStream como saída padrão. Quando o comando
    //System.out.println for chamado, o conteúdo será escrito na variável outContent.
    //Dessa forma, você poderá verificar o que está sendo escrito no out.
    @Before
    public void setup() {
        System.setOut(new PrintStream(outContent));
        // Você também pode passar o seu InputStream para o System. Dessa forma, você não precisa inputar dados
        // no console.
        InputStream inputStram = new ByteArrayInputStream(getInput().getBytes());
        System.setIn(inputStram);
    }

    @After
    public void tearDown() throws IOException {
        outContent.close();
        System.setOut(null);
        System.setIn(null);
    }

    //Testa se as mensagens impressas pelo método estão corretas
    @Test
    public void pegarDadosTest() {
        Cliente.pegarDados();
        Assert.assertEquals(getExpected(), outContent.toString());
    }

    private String getInput() {
        StringBuilder builder = new StringBuilder();
        builder.append("João\n");
        builder.append("123\n");
        builder.append("456\n");
        builder.append("Estado\n");
        builder.append("Cidade\n");
        builder.append("1");
        return builder.toString();
    }

    private String getExpected() {
        StringBuilder builder = new StringBuilder();
        builder.append("Informe o nome\n");
        builder.append("Informe CPF\n");
        builder.append("Informe telefone\n");
        builder.append("Informe o estado\n");
        builder.append("Informe a cidade\n");
        builder.append("Informe o número do do convênio\n");
        return builder.toString();
    }
}

However, as already mentioned in the comments of your question. This test of yours is not necessary. What you have to test is the return of your method and not what it is doing in the middle. In this case, what you could test is whether the returned Client object is the expected one. Check the System.out.println is useful when the method is void and it prints some message on the console when it runs successfully or when it gives some error.

A more interesting test would be this:

//Testa se o cliente foi montado corretamente
    @Test
    public void pegarDadosClientTest() {
        Cliente atual = Cliente.pegarDados();
        Cliente expected = getClienteExpected();
        Assert.assertEquals(expected.getNome(), atual.getNome());
        Assert.assertEquals(expected.getCpf(), atual.getCpf());
        Assert.assertEquals(expected.getTelefone(), atual.getTelefone());
        Assert.assertEquals(expected.getEstado(), atual.getEstado());
        Assert.assertEquals(expected.getCidade(), atual.getCidade());
        Assert.assertEquals(expected.getNumeroConvenio(), atual.getNumeroConvenio());
    }

    private Cliente getClienteExpected() {
        Cliente cliente = new Cliente("João", 123, 456, "Estado", "Cidade", 1);
        return cliente;
    }

This code snippet you can use inside the previous code class.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.