用于复杂Java模型的JUnit测试

用于复杂Java模型的JUnit测试,java,unit-testing,junit,composite,Java,Unit Testing,Junit,Composite,我想学习/知道如何使用JUnit测试复杂的java类 我有一个java项目,从属性文件中读取内容 ,然后将文件内容解析为java对象。属性文件有一个树结构,因此我实现了Java模型,类似于复合模式。 所以,当我想为复合类或项目的任何类编写单元测试时,我应该如何编写这些测试?测试应该是什么样子?应该是这样吗 @Test public void testComposition() { // Create a object of the Composite class, what y

我想学习/知道如何使用JUnit测试复杂的java类

我有一个java项目,从属性文件中读取内容 ,然后将文件内容解析为java对象。属性文件有一个树结构,因此我实现了Java模型,类似于复合模式。

所以,当我想为复合类或项目的任何类编写单元测试时,我应该如何编写这些测试?测试应该是什么样子?应该是这样吗

 @Test
 public void testComposition()
 {
     // Create a object of the Composite class, what you expect after reading
     // from the file
     Composite expectedObject = new Composite();
     ...

     // Call the parser class of the file which returns a composite
     Composite createdObject = PropertiesFileParser.parse(file);

     // and then i have to assert the 2 object with a method from Assert 
     // e.g.
     assertEqual(createdObject, expectedObject);
 }
我是否必须“手动”创建预期的复合对象?或者有没有其他方法来做类似的事情

在编写Junit测试用例时是否有一些编码约定


我很感激每一个有用的答案!(请原谅我的英语)

首先,你应该检查你的对象的每个方法。所以,如果我是你,我会通过调用单独的leaf和composite方法来检查一些小模型的小例子。例如,我会:

  • 创建一个组合
  • 确保没有孩子
  • 确保它优雅地拒绝移除它不拥有的孩子
  • 添加一个孩子
  • 确保它有一个孩子
  • 确保它仍然优雅地拒绝移除它不拥有的孩子
  • 再添加一个子项
  • 确保它有两个孩子
  • 确保它优雅地拒绝添加它已经包含的子级
  • 移除第一个孩子
  • 确保它有一个孩子
  • 移除第二个子对象
  • 确保没有孩子
  • 确保它优雅地拒绝移除它不再拥有的孩子
  • 然后,您需要编写一些测试来确保对象的
    equals()
    方法绝对正确地工作,因为稍后junit的
    assertEqual()
    将大量调用此方法。所以,如果我是你,我会:

  • 创建单个对象a
  • 将a的副本创建为B
  • 确保A等于B
  • 创建一个a作为C的副本,并稍加修改
  • 确保A不等于C
  • 创建一个as D的副本,并稍加修改
  • 确保A不等于D
  • 创建一个as E的副本,并稍加修改
  • 确保A不等于E
  • …以此类推,直到您确信在未经测试的
    Leaf.equals()
    Composite.equals()
    方法中绝对不会发生任何事情

    然后,您应该手动测试微小层次结构的基础。因此:

  • 创建一个小层次结构(只有一个父级和一个子级)
  • 创建一个与a相同的小层次结构B
  • 确保A等于B
  • 创建一个小的层次结构X,它在微小的细节上与a不同
  • 确保A不等于X
  • 创建一个小的层次结构Y,它在另一个小细节上不同于a
  • 确保A不等于Y
  • 创建一个小层次Z,它在另一个小细节上与a不同
  • 确保A不等于Z
  • 完成以上所有操作后,就可以点击磁盘了


    点击磁盘是为了确保模型的复杂实例化仍然有效。您可以编写
    属性FileWriter
    将层次结构写入文件,这样您就可以创建一个对象层次结构,将其写入文件,然后将文件读入另一个对象层次结构,并比较这两个对象层次结构。

    要使测试非常简单且可读,您可以创建如下内容

    @Test
     public void testComposition()
     {
         // given
         Composite expectedObject = getExpectedComposite();
    
         // when
         Composite createdObject = PropertiesFileParser.parse(file);
    
         // then
         assertTrue(areCompositesEquals(createdObject, expectedObject));
     }
    
    private Composite getExpectedComposite() {
        Composite composite = new Composite();
        // construct a composite you expect after reading from file
    
        return composite;
    }
    
    
    private static boolean areCompositesEquals(Composite createdObject,
            Composite expectedObject) {
    
        // assert...
        // assert...
        // assert...
        // list of asserts here that check the composites are equals (number of children and other condition)
    
        return true;
    }
    

    为了避免磁盘上的I/O操作,可以为测试文件创建模拟

    我必须为我的案例实现
    assertEqual(…)
    方法吗?嗯,
    assertEqual()
    是junit方法,因此您无法实现它,但它调用对象的
    equals()
    方法,因此,这实际上是您必须实现的,并确保它完全正确工作。感谢您的详细回答@Mike Nakis!:)@T.C.我修改了它,使它更加详细。