我对java编程很陌生,但我会尝试使用正确的术语,尽可能避免误解。
我找到了一些与我的问题非常相似的主题的答案,但或者我只是看不出他们如何真正适合我的问题,或者他们真的只是不适合。他们中的一些人使用模拟对象,但我不确定这是我的正确选择。
我需要一个对象数组,从随机访问的二进制文件中加载信息。二进制文件的第一个字节是文件的标题,它定义了数据如何存储在文件中,基本上表示某些字段的长度有助于计算文件中所需数据的位置。
所以现在我想测试将被调用的方法,以便将 UnitListElement 对象指定的所需数据加载到 Unit 对象。为此,我只专注于单个读取二进制文件。
我有一个名为 Unit 的java类,带有一些属性,比方说 a ,* b *和 c 。使用方法调用 getDataFromBinFile 加载此属性的值:
public class Unit{
public double[] a;
public double[] b;
public double[] c;
getDataFromBinFile(UnitListElement element){
<here loads the data from the binary file with random access>
}
}
从二进制文件加载数据的方法,打开二进制文件并访问二进制文件中的所需数据。要读取的所需数据在 UnitListElement 对象中指定:
public class UnitListElement{
public String pathOfFile;
public int beginToReadAt; // info related to where the desired data begins
public int finishReading; // info related to where the desired data ends
}
使用的属性 beginToReadAt 和 finishReading 时间引用以及二进制文件的标头,用于计算从二进制文件中读取的第一个和最后一个字节位置。
所以我需要做的是一个测试,我调用方法 getDataFromBinFile(unitListEl)并测试返回的信息是否正确。
第一个选项
在一些有类似问题的帖子中建议使用模拟对象。我试图找到关于模拟对象的文档,但我还没有找到任何简单的初学者指南。因此,虽然不太了解模拟对象,但我的印象是不适合这种情况,因为我想要测试的是读取二进制文件,而不仅仅是与其他对象的交互。
第二个选项
另一种选择是使用辅助方法f.i为测试内部的测试创建二进制文件。使用@BeforeClass,并使用此临时文件运行测试,然后使用@AfterClass方法将其删除。
您认为考虑TDD方法的最佳做法是什么?模拟对象真的适合这种情况吗?如果他们这样做,是否有任何关于初学者的基本示例的文档?
或另一方面,文件的创建更适合测试阅读方法吗?
提前多多感谢。
答案 0 :(得分:1)
模拟可以应用于您的案例,但事实上这并非严格必要。您所需要的只是将getDataFromBinFile
中的实际数据处理逻辑与从文件中读取字节的代码分离。
您可以(至少)以两种方式实现这一目标:
UnitListElement
并返回字节数组,然后在getDataFromBinFile
中使用它。然后,您可以使用模拟阅读器在测试中模拟此接口,模拟阅读器只返回一些预定义的字节而无需访问任何文件(或者,您可以将文件读取逻辑移动到UnitListElement
本身,因为现在它似乎是一个POD类。)getDataFromBinFile
的签名以获取字节数组参数而不是UnitListElement
。在您的真实生产代码中,您可以从UnitListElement
描述的文件位置读取数据,然后将其传递给getDataFromBinFile
。在单元测试中,您可以直接将任何二进制数据传递给它。 (请注意,在这种情况下,将方法重命名为getDataFromBytes
。)对于模拟,到目前为止我一直在使用EasyMock。我发现its documentation相当容易理解,希望有所帮助。
答案 1 :(得分:0)
我对TDD没有多少经验。在测试对文件的读/写时,不需要使用模拟,最好的选择是测试运行的文件的测试版本。当您无法轻松为您的用例创建可测试对象时,即使您正在测试与服务器的交互时,可以使用模拟。
答案 2 :(得分:0)
我不喜欢创建测试二进制文件,因为正在读取的文件格式的任何更改都意味着更改测试文件(以及测试)。
由于您正在遵循TDD方法,因此您必须为&#34; UnitListElement&#34;编写测试。因此,对于情况来说,嘲弄似乎是一个更好的解决方案。你的目标是测试&#34; getDataFromBinFile&#34;方法而不是&#34; UnitListElement&#34;类方法(当前)因此你可以模拟&#34; UnitListElement&#34; class(或由它继承并传递给getDataFromBinFile方法的接口)。 Mocking&#34; UnitListElement&#34;意味着只要在&#34; getDataFromBinFile&#34;中访问它,就可以将预定义或任何特定的返回值返回给类中的任何方法调用。方法 。最后,您可以在&#34; getDataFromBinFile&#34;中使用模拟中返回的值。执行业务逻辑后,方法和断言方法的返回值。我没有使用太多的模拟框架,但是大多数时候我一直在使用EasyMock框架。首先,您可以获得EasyMock的基本示例here
答案 3 :(得分:0)
只需制作测试二进制文件。
此过程正在读取文件。所以没有理由担心文件系统。该文件将始终是确定性的(如果您在另一个故事的阅读中更改了文件)
如果您想在读完对象后对对象进行测试,我建议您在测试中创建它们(除非这很难做,如声音文件)
另外,我建议抽象流而不是文件,但我仍然会用测试文件测试它。顺便说一句:确保测试文件很小,毕竟这是一个测试。
有些人可能会争辩说“测试不应该打到文件系统”,但你认为从哪里加载.class文件?
另外,我会通过java classLoader获取流
this.getClass().getResourceAsStream("yourfile.name");
快乐的测试!
Llewellyn Falco