Nair Ajit
Nair Ajit

Reputation: 19

How to Unit test the java code

How to unit test this code using 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();
    }
  } 
}

I am new at unit testing want some guidance on unit testing .

Output when num=3

   *
  * *
 * * *
  * *
   *

this is how the output should be, num indicates the star in center line

Upvotes: 2

Views: 762

Answers (3)

Marco Forberg
Marco Forberg

Reputation: 2644

instead of printing your shape directly you could store the shape in an 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;
    } 
}

now you can test your code:

@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));
}

to print your shape simply call

diamond.printShape(System.out);

the inner part of you loops for the upper and lower half are quite the same and could be refactored into an own method.

Upvotes: 0

Philipp
Philipp

Reputation: 69703

In order to test a method it has to do one of these:

  • return a value you can compare with an expected value
  • change the state of an object which gets passed to it
  • throw an exception you can catch
  • change some state of the object which you can verify by calling another method

For that reason, methods which returns void and just write their result to System.out should generally be avoided.

To fix this issue you can do one of these:

  • Return a String instead of writing to stdout.
  • Make the method take an PrintStream object and write to that. System.out is a PrintStream object, so you can pass it in production code. In your test code, however, you can pass your own PrintStream object which doesn't write to stdout but instead allows to check what was written to it. This technique is called Dependency Injection.
  • Make the method write to a private PrintStream or String, and add two new methods to the class. One to get the content of that variable so you can test that it is correct and one to write that variable to System.out.

Upvotes: 2

Bhushan Bhangale
Bhushan Bhangale

Reputation: 10987

Instead of doing sysout you should refactor and make your method return the output. You can then verify the output.

The other option is in your junit test create a Output stream and set it on the

System.setOut(your output stream);

You can then verify the output stream.

But this is not reliable as if your program executes some other code which also writing to the sysout then your output stream will have that data also.

Upvotes: 4

Related Questions