目的:使用TDD(我最近了解到现在对此感到遗憾)构建一个stickynote应用程序
问题:我希望所有“注释”将由自己的单独类进行序列化和反序列化。我希望使用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()
);
}
}
这使我陷入无限循环,这让我发疯。
问题:如何测试反序列化类?上面的代码我在做什么错了?
答案 0 :(得分:0)
我会在您的应用中添加一个文件,然后将其加载以进行测试。
@Test
public void givenUsingPlainJava_whenConvertingFileToInputStream_thenCorrect()
throws IOException {
File initialFile = new File("src/main/resources/sample.txt");
InputStream targetStream = new FileInputStream(initialFile);
}
答案 1 :(得分:0)
对于可能面临相同问题的其他任何人,请重写Note类的hashCode()和equals()方法,使其按我预期的方式工作。将列表实例化为ArrayList或LinkedList。这为我解决了。我不知道的一件事是如何与它一起使用Mockito。因此,我接受了@PhilNinan的建议,并将TemporaryFolder与tempFile一起使用。然后序列化到该文件并读取该文件(不理想,但找不到其他方法)。 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
);
}
}