如何对java代码进行单元测试

时间:2013-04-15 08:05:00

标签: java junit

如何使用Junit对此代码进行单元测试

public class Diamond {

   public void DiamondShape(int num) {

       for(int ucount=num;ucount>0;ucount--) {
    //Loop to print blank space
        for(int count_sp=1;count_sp<ucount;count_sp++)
            System.out.printf(" ");
    //Loop to print *
        for(int count_ast=num;count_ast>=ucount;count_ast--)
            System.out.printf("* ");
        System.out.println();
       }
//Loop for lower half
  for(int lcount=1;lcount<num;lcount++) {
    //Loop to print blank space
    for(int count_sp=0;count_sp<lcount;count_sp++)
            System.out.printf(" ");
    //Loop to print *
        for(int count_ast=num-1;count_ast>=lcount;count_ast--)
            System.out.printf("* ");
    System.out.println();
    }
  } 
}

我是单元测试的新手,需要一些关于单元测试的指导。

num = 3

时的输出
   *
  * *
 * * *
  * *
   *

这是输出的方式,num表示中心线上的星号

3 个答案:

答案 0 :(得分:4)

您应该重构并使您的方法返回输出,而不是执行sysout。然后,您可以验证输出。

另一个选项是在你的junit测试中创建一个输出流并在

上设置它
System.setOut(your output stream);

然后,您可以验证输出流。

但这不可靠,好像你的程序执行了一些其他代码也写入了sysout,那么你的输出流也会有这些数据。

答案 1 :(得分:2)

为了测试方法,它必须执行以下操作之一:

  • 返回一个可以与预期值进行比较的值
  • 更改传递给它的对象的状态
  • 抛出一个你可以抓住的例外
  • 通过调用其他方法来更改可以验证的对象的某些状态

出于这个原因,通常应该避免返回void并将结果写入System.out的方法。

要解决此问题,您可以执行以下操作之一:

  • 返回一个String而不是写入stdout。
  • 使方法采用PrintStream对象并写入。 System.out是一个PrintStream对象,因此您可以在生产代码中传递它。但是,在测试代码中,您可以传递自己的PrintStream对象,该对象不会写入stdout,而是允许检查写入的内容。这种技术称为Dependency Injection
  • 使方法写入私有PrintStream或String,并向该类添加两个新方法。一个获取该变量的内容,以便您可以测试它是否正确,并将该变量写入System.out。

答案 2 :(得分:0)

而不是直接打印您的形状,您可以将形状存储在ArrayList<String>

public class Diamond {
    private List<String> shape = null;

    public void createShape(int num) {
        shape = new ArrayList<String>();
        String shapeLine = "";
        for(int ucount=num;ucount>0;ucount--) {
            for(int count_sp=1;count_sp<ucount;count_sp++) {
                shapeLine += " ";
            }
            for(int count_ast=num;count_ast>=ucount;count_ast--) {
                shapeLine += "* ";
            }
            shape.add(shapeLine);
        }

        shapeLine = "";
        for(int lcount=1;lcount<num;lcount++) {
           for(int count_sp=0;count_sp<lcount;count_sp++) {
                shapeLine += " ";
           }
           for(int count_ast=num-1;count_ast>=lcount;count_ast--) {
               shapeLine += "* ";
           }
           shape.Add(shapeLine);
        }
    } 

    public void printShape(OutStream out) {
        if(shape != null) {
            for(String shapeLine : shape) {
                out.println(shapeLine);
            }
        }
    }

    public List<String> getShape() {
        return shape;
    } 
}

现在您可以测试您的代码:

@Test
public void testShape() {
    Diamond diamond = new Diamond();
    diamond.createShape(3);
    List<String> shape = diamond.getShape();

    assertNotNull(shape);
    assertEquals(5, shape.size());
    assertEquals("  * ", shape.get(0));
    assertEquals(" * * ", shape.get(1));
    assertEquals("* * * ", shape.get(2));
    assertEquals(" * * ", shape.get(3));
    assertEquals("  * ", shape.get(4));
}

打印你的形状只需调用

diamond.printShape(System.out);

上半部分和下半部分的内部部分完全相同,可以重构为自己的方法。