Как покрыть частных участников класса stati c final модульным тестом exp serialVersionUID - PullRequest
0 голосов
/ 14 января 2020

Я добавляю модульные тесты, чтобы покрыть устаревший java проект (который я не могу изменить),

Я знаю, как провести модульное тестирование и охватить этот класс, я сделал это, добавив модульный тест ниже.

public class Thing implements Serializable {

    private static final long serialVersionUID = -1463850548670691860L;

    private String id;
}

Unsing, например:

class ThingTest {

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

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

Но эхолот и jacoco показывают serialVersionUID как не покрытый. который является звуком.

enter image description here

Не могли бы вы предложить решение, которое порадует гидролокатор, покрыв это поле.

Да Я знаю, я не должен следовать инструменту, но практике.

Другие противопоказания, я не могу изменить видимость serialVersionUID.

Спасибо

Ответы [ 2 ]

0 голосов
/ 14 января 2020

Ваша тестовая система покрытия говорит: "никто не имеет доступа к этому полю во время ваших юнит-тестов". Вот что означает красная полоса. Поэтому, чтобы получить его на go, вам нужно запустить код, который обращается к этому полю. Использование отражения для доступа к полю для увеличения охвата модульных тестов - нонсенс. Даже если оно может сделать поле зеленым, оно фактически не использует поле осмысленно.

Правильный способ сделать это - использовать тестовый класс таким образом, чтобы использовать это поле. SerialVersionUID используется во время сериализации / десериализации, чтобы решить, соответствуют ли считываемые байты объекту, который вы пытаетесь создать.

Вот простой пример, который охватывает то, что вы хотите. Я добавил тест на равенство в конце, потому что это действительно , что вы должны тестировать, когда вы обеспокоены процессом сериализации / десериализации.

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

Так что сделайте выше, но замените Foo с вашим собственным классом, и вы должны получить покрытие.

0 голосов
/ 14 января 2020

Если в вашем JUnit вы расширяете ObjectInputString, вы можете прочитать serialVersionUID при десериализации сериализованного вами объекта:

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

...