Como cobrir serialVersionUID por teste de unidade

votos
0

Estou adicionando testes unitários para cobrir um projet legado java,

Eu sei como teste de unidade e cobrir essa classe, eu fi-lo adicionando o abaixo teste de unidade.

public class Thing implements Serializable {

    private static final long serialVersionUID = -1463850548670691860L;

    private String id;
}

unsing por exemplo:

classe ThingTest {

@Test
void testShouldNotChangeSerialVersionUID() throws NoSuchFieldException {
    final Field serialVersionUID = Thing.class.getDeclaredField(serialVersionUID);
    serialVersionUID.setAccessible(true);

    assertEquals(-1463850548670691860L, getField(serialVersionUID, new Thing()));
}

}

Mas sonar e jacoco show como não serialVersionUID coberto. que é sólida.

digite

O senhor poderia sugerir uma solução para fazer feliz sonar, cobrindo neste campo.

obrigado

Publicado 14/01/2020 em 00:05
fonte usuário
Em outras línguas...                            


2 respostas

votos
-1

Se em seu JUnit você estender a ObjectInputString você pode ler o serialVersionUID enquanto desserializar o objeto que você serializado:

     private class MyObjectInputStream extends ObjectInputStream {

        public long uid;

        public MyObjectInputStream(InputStream in) throws IOException {
            super(in);
        }

        @Override
        protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
            ObjectStreamClass readClassDescriptor = super.readClassDescriptor(); //To change body of generated methods, choose Tools | Templates.
            uid = readClassDescriptor.getSerialVersionUID();
            return readClassDescriptor;
        }



    }

    @Test
    public void testSomeMethod() throws IOException, ClassNotFoundException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(byteArrayOutputStream);
        oos.writeObject(new Thing());
        MyObjectInputStream myObjectInputStream = new MyObjectInputStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()));
        myObjectInputStream.readObject();
        assertEquals(-1463850548670691860L, myObjectInputStream.uid);
    }

Respondeu 14/01/2020 em 00:31
fonte usuário

votos
0

Seu sistema de cobertura de teste está dizendo "ninguém nunca acessa esse campo durante os testes de unidade". Isso é o que os meios de barras vermelhas. Então, para fazê-lo ir embora você precisa para executar o código que acessa esse campo. Usando reflexão para acessar o campo para aumentar a cobertura de teste de unidade é um disparate. Mesmo que possa transformar o campo verde, não é, na verdade, usando o campo de uma forma significativa.

A maneira certa de fazer isso é exercer a classe de teste de uma forma que usos nesse campo. O serialVersionUID é usado durante a serialização / desserialização para decidir se os bytes que estão sendo lidos coincidir com o objeto que você está tentando criar uma instância.

Aqui está um exemplo simples que cobre o que você quer. Eu adicionei um teste de igualdade no final, porque isso é realmente o que você deve estar testando quando você está preocupado com o processo de serialização / desserialização.

package org.does.not.exist;

import org.junit.jupiter.api.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

import static org.assertj.core.api.Assertions.assertThat;

class Foo implements Serializable {
     private static final long serialVersionUID = 42L;

    public Foo(String value) {
        this.value = value;
    }

    private String value;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Foo)) return false;

        Foo foo = (Foo) o;

        return value != null ? value.equals(foo.value) : foo.value == null;
    }

    @Override
    public int hashCode() {
        return value != null ? value.hashCode() : 0;
    }
}

class StackoverflowTest {

    @Test
    void test() throws Exception {
        Foo foo = new Foo("a string!");

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream out = new ObjectOutputStream(bos);
        out.writeObject(foo);

        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        ObjectInputStream in = new ObjectInputStream(bis);
        Foo copied = (Foo) in.readObject();

        assertThat(foo).isEqualTo(copied);
    }
}

Então, fazer o acima, mas substitua Foo com sua própria classe e você deve obter cobertura.

Respondeu 14/01/2020 em 01:17
fonte usuário

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more