Невозможно протестировать класс десериализации с использованием JUnit и Mockito - PullRequest
0 голосов
/ 14 января 2019

Цель: создать приложение stickynote с использованием TDD (о котором я недавно узнал и теперь активно сожалею)

Проблема: я ожидаю, что все «Заметки» будут сериализованы и десериализованы их отдельными классами. И я хочу использовать подход TDD, но я не могу даже протестировать удачный путь класса NoteReader (десериализатор), не говоря уже о угловых случаях.

Вот код:

package com.domainname.applicationname;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.List;

public class NoteReader {
    private final FileInputStream fileInputStream;

    public NoteReader(FileInputStream fileInputStream) {
        this.fileInputStream = fileInputStream;
    }

    @SuppressWarnings("unchecked")
    public List<Note> load() {
        ObjectInputStream objectInputStream = null;
        List<Note> output = null;
        try {
            objectInputStream = new ObjectInputStream(fileInputStream);
            output = (List<Note>) objectInputStream.readObject();
            objectInputStream.close();
        } catch (ClassNotFoundException | IOException e) {
            e.printStackTrace();
        }
        return output;
    }
}

и вот код модульного тестирования:

package com.domainname.applicationname;

import org.junit.*;
import org.mockito.Mockito;

import java.io.*;
import java.util.Arrays;
import java.util.List;

public class NoteReaderTest {
    private FileInputStream dummyFileInputStream;
    private NoteReader noteReaderDummy;

    private List<Note> expectedOutput = Arrays.asList(
            new Note("some written text"),
            new Note("some other written text", NoteColor.lightGreen)
    );

    private ByteArrayOutputStream byteArrayOutputStream;
    private ObjectOutputStream objectOutputStream;
    private byte[] bytesToBeDeserialized;

    @Before
    public void setUp() throws IOException {
        dummyFileInputStream = Mockito.mock(FileInputStream.class);
        noteReaderDummy = new NoteReader(dummyFileInputStream);

        byteArrayOutputStream = new ByteArrayOutputStream();
        objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
    }

    @After
    public void tearDown() throws IOException {
        noteReaderDummy = null;
        byteArrayOutputStream.flush();
        objectOutputStream.flush();
        objectOutputStream.close();
    }

    @Test
    public void shouldLoadTheListOfNotes() throws IOException {
        //given
        objectOutputStream.writeObject(expectedOutput);
        bytesToBeDeserialized = byteArrayOutputStream.toByteArray();
        int intValueOfByteArray = dummyFileInputStream.read(bytesToBeDeserialized);
        //when
        Mockito.when(
                dummyFileInputStream.read()
        ).thenReturn(
                intValueOfByteArray
        );

        //then
        Assert.assertEquals(
                "the notes have not been loaded",
                expectedOutput,
                noteReaderDummy.load()
        );
    }
}

У меня бесконечный цикл, и это сводит меня с ума.

Вопрос: Как проверить класс десериализации? Что я делаю не так в приведенном выше коде?

Ответы [ 2 ]

0 голосов
/ 18 января 2019

Для всех, кто может столкнуться с той же проблемой, переопределите методы hashCode () и equals () класса Note, чтобы они работали так, как я намереваюсь. Создайте список для ArrayList или LinkedList. Это решило это для меня. Единственное, что я не мог понять, это как использовать Mockito с ним. Поэтому я воспользовался советом @PhilNinan и использовал TemporaryFolder с временным файлом. Затем сериализовать в этот файл и прочитать этот файл (не идеально, но не мог найти другой путь). NoteReader:

package com.somedomainname.someapplication;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.List;

class NoteReader {
    private final FileInputStream fileInputStream;

    NoteReader(FileInputStream fileInputStream) {
        this.fileInputStream = fileInputStream;
    }

    @SuppressWarnings("unchecked")
    List<Note> load() throws IOException {
        ObjectInputStream objectInputStream = null;
        List<Note> output = new ArrayList<>();

        try {
            objectInputStream = new ObjectInputStream(fileInputStream);
            while (fileInputStream.available() != 0) {
                Note n = (Note) objectInputStream.readObject();
                output.add(n);
            }

        } catch (ClassNotFoundException | IOException e) {
            fileInputStream.close();
            assert objectInputStream != null;
            objectInputStream.close();

            e.printStackTrace();
        }
        return output;
    }

}

Класс NoteReaderTest:

package com.somedomainname.someapplicationname;

import org.junit.*;
import org.junit.rules.TemporaryFolder;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class NoteReaderTest {
    private NoteReader noteReaderDummy;

    private ObjectOutputStream objectOutputStream;

    @Rule
    public TemporaryFolder temporaryFolder = new TemporaryFolder();

    private File tempFile;

    private static List<Note> inputList = new ArrayList<>();
    static {
        inputList.add(new Note("some written text"));
        inputList.add(new Note("some other written text", NoteColor.lightGreen));
    }

    private static List<Note> anotherList = new ArrayList<>();
    static {
        anotherList.add(new Note("qazwsxedcrfv"));
        anotherList.add(new Note("qwertyuiopasdfghjkl", NoteColor.lightRed));
    }

    @Before
    public void setUp() throws IOException {
        tempFile = temporaryFolder.newFile("someBullshit.ser");
        objectOutputStream = new ObjectOutputStream(new FileOutputStream(tempFile));

        for(Note n : inputList) {
            objectOutputStream.writeObject(n);
        }

        noteReaderDummy = new NoteReader(new FileInputStream(tempFile));

    }

    @After
    public void tearDown() throws IOException {
        objectOutputStream.flush();
        objectOutputStream.close();
        tempFile = null;
        temporaryFolder = null;
        noteReaderDummy = null;

    }

    /**
     * This test method tests the happy path of the NoteReader.load() method.
     * @throws IOException
     */

    @Test
    public void shouldLoadTheListOfNotes() throws IOException {
        //given

        //then
        List<Note> output = noteReaderDummy.load();
        Assert.assertEquals(
                "the notes have not been loaded",
                inputList,
                output
        );

    }

    /**
     * This test method is responsible for confirming that the output of the
     * NoteReader.load() method doesn't stray from the expected one.
     * @throws IOException
     */

    @Test
    public void shouldNotLoadTheOtherListOfNotes() throws IOException {
        //given

        //then
        List<Note> output = noteReaderDummy.load();
        Assert.assertNotEquals(
                "it loaded the wrong fucking list",
                anotherList,
                output
        );

    }

    /**
     * this test method is responsible for checking that the output of
     * the method NoteReader.load() is not null
     * @throws IOException
     */

    @Test
    public void shouldNotBeNull() throws IOException {
        //given

        //then
        List<Note> output = noteReaderDummy.load();
        Assert.assertNotNull(
                "fuck it's null",
                output
        );
    }
}
0 голосов
/ 14 января 2019

Я бы добавил файл в ваше приложение и просто загрузил его для тестирования.

@Test
public void givenUsingPlainJava_whenConvertingFileToInputStream_thenCorrect() 
  throws IOException {
    File initialFile = new File("src/main/resources/sample.txt");
    InputStream targetStream = new FileInputStream(initialFile);
}

https://www.baeldung.com/convert-file-to-input-stream

...