Wie decken serialVersionUID von Unit-Test

stimmen
0

Ich füge Unit-Tests ein Vermächtnis Java-projet zu decken,

Ich weiß, wie Unit-Test und decken diese Klasse, ich habe es durch das Gerät zu testen unten hinzufügen.

public class Thing implements Serializable {

    private static final long serialVersionUID = -1463850548670691860L;

    private String id;
}

unsing zum Beispiel:

Klasse ThingTest {

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

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

}

Aber Sonar und jacoco zeigen serialVersionUID als nicht abgedeckt. Das ist Klang.

Geben

Könnten Sie bitte eine Lösung zu machen Sonar glücklich durch Abdecken dieses Feld vor.

Vielen Dank

Veröffentlicht am 14/01/2020 um 00:05
quelle vom benutzer
In anderen Sprachen...                            


2 antworten

stimmen
-1

Wenn in Ihrem JUnit Sie Erweitere ObjectInputString Sie die serialVersionUID lesen kann, während Deserialisieren Sie das Objekt serialisiert:

     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);
    }

Beantwortet am 14/01/2020 um 00:31
quelle vom benutzer

stimmen
0

Ihre Testabdeckung System sagt, „niemand greift auf dieses Feld während der Unit-Tests“. Das ist, was die roten Balken bedeutet. Also, um es Sie Code ausführen müssen gehen weg, die das Feld zugreift. Reflexion für den Zugriff über die Feldeinheit Testabdeckung ist Unsinn zu erhöhen. Auch wenn es das Feld grün kann, dann ist es nicht wirklich das Feld in einer sinnvollen Art und Weise verwendet wird.

Der richtige Weg, dies zu tun ist, um die Testklasse in einer Weise, dass Anwendungen dieses Feld auszuüben. Die serialVersionUID wird bei der Serialisierung / Deserialisierung verwendet, um zu entscheiden, ob der Bytes, die Lese des Objekts Übereinstimmen sein werden, dass Sie instantiate versuchen.

Hier ist ein einfaches Beispiel , dass Abdeckungen , was Sie wollen. Ich habe am Ende ein Gleichheitstest , denn das ist wirklich , was Sie sollten testen, wenn Sie über die Serialisierung / Deserialisierung betroffen sind.

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);
    }
}

Gehen Sie also wie oben, aber ersetzen Foo mit Ihrem eigenen Klasse und Sie sollten Abdeckung erhalten.

Beantwortet am 14/01/2020 um 01:17
quelle vom benutzer

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