Как покрыть serialVersionUID с помощью модульного тестирования

голоса
0

Я добавляю модульные тесты для покрытия устаревшего Java PROJET,

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

public class Thing implements Serializable {

    private static final long serialVersionUID = -1463850548670691860L;

    private String id;
}

unsing, например:

класс ThingTest {

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

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

}

Но гидролокатор и jacoco шоу serialVersionUID не охвачены. который является звук.

введите

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

Благодарность

Задан 14/01/2020 в 00:05
источник пользователем
На других языках...                            


2 ответов

голоса
-1

Если в вашем 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);
    }

Ответил 14/01/2020 в 00:31
источник пользователем

голоса
0

Ваша система тестового покрытия говорит «никто никогда не обращается к этому полю во время модульных тестов». Это то, что красный прямоугольник средства. Таким образом, чтобы заставить его уйти вам нужно запустить код, обращающийся это поле. Использование отражения для доступа к полю, чтобы увеличить охват модульного тестирования нонсенс. Несмотря на то, что может превратить поле зеленого цвета, на самом деле это не с помощью поля в значительной степени.

Правильный способ сделать это, чтобы осуществить тестовый класс таким образом, что использует это поле. 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 со своим собственным классом, и вы должны получить освещение.

Ответил 14/01/2020 в 01:17
источник пользователем

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