Jake B Jake B - 2 months ago 25
Java Question

How do I simulate multiple inputs from a JUnit test case into my program?

I have written a program which looks like this:

import java.util.Scanner;
import java.util.ArrayList;

public class Triangles {

public static void main(String[] args) {

Scanner user_input = new Scanner(System.in);

ArrayList<String> triangleLengths = new ArrayList<String>();

for (int i=0; i < 3; i++) {

System.out.print("Triangle length #" + i + ": ");
triangleLengths.add(i,user_input.next());
}

if (triangleLengths.get(0) == triangleLengths.get(1) && triangleLengths.get(1) == triangleLengths.get(2)) {

System.out.println("This triangle is an equilateral triangle");

} else if (triangleLengths.get(0) == triangleLengths.get(1) || triangleLengths.get(0) == triangleLengths.get(2) || triangleLengths.get(1) == triangleLengths.get(2)) {

System.out.println("This triangle is an isosceles triangle");

} else if (triangleLengths.get(0) != triangleLengths.get(1) && triangleLengths.get(1) != triangleLengths.get(2)) {

System.out.println("This triangle is a scalene triangle");

} else {

System.out.println("The input does not make a triangle!");

}


}


}

I have been tasked with writing a JUnit test case to essentially try and 'break' my program through testing with various inputs. I can't for the life of me figure out how to do this as a total Java newbie - could anyone point me in the right direction?

Answer

So I made a suggestion on how to solve it.

you want to make it so that you can test with different parameters automatically without needing to enter it manually so i isolated the triangles part as seen below.

EDIT: I redid the code somewhat

The normal run class src/main.java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner user_input = new Scanner(System.in);
        List<String> triangleLengths = new ArrayList<>();

        for (int i = 0; i < 3; i++) {
            System.out.print("Triangle length #" + i + ": ");
            triangleLengths.add(i, user_input.next());
        }

        // Result output will be here
        Triangle subject = new Triangle(triangleLengths);
        if (subject.getTriangleType() == Triangle.Type.INVALID) {
            System.out.println("Triangle is invalid");
        } else {
            System.out.println("Triangle is: " + subject.getTriangleType());
        }
    }
}

The JUnit class test/TrianglesTest.java

import org.junit.Test;

import java.util.Arrays;
import java.util.List;

import static org.junit.Assert.assertEquals;

public class TrianglesTest {

    /**
     * Testing with String inputs (what you'd enter manually)
     */
    @Test
    public void testWithStrings() {
        List<String> triangleLengths = Arrays.asList("len1", "len2", "len3");

        Triangle subject = new Triangle(triangleLengths);
        // Example of checking if expected type
        assertEquals(Triangle.Type.ISOSCELES, subject.getTriangleType());
    }

    /**
     * Testing with numbers as what I'd expect the triangle to be made of
     *
     * Here you test with a triangle object
     *
     * Haven't tested what the 3 types is sorry :O
     */
    @Test
    public void testWithNumbersAsObject() {
        Triangle subject = new Triangle(4, 5.32, 7);
        assertEquals(Triangle.Type.SCALENE, subject);
    }

    /**
     * This piece you check the static method but have no object
     */
    @Test
    public void testWithNumbersStaticMethod() {
        assertEquals(Triangle.Type.ISOSCELES, Triangle.getTriangleType(3.4d, 4d, 1.111d));
    }
}

And lastly the actual code you wanted to test src/Triangles.java

import java.util.List;

/**
 * I created so you can both have an object of the triangle or make the check purely static
 * maybe you need an object type for later?
 */
public class Triangle {

    final double side0;
    final double side1;
    final double side2;

    public Triangle(List<String> triangleLengths) {
        this(Double.parseDouble(triangleLengths.get(0)),
                Double.parseDouble(triangleLengths.get(1)),
                Double.parseDouble(triangleLengths.get(2)));
    }

    public Triangle(double side0, double side1, double side2) {
        this.side0 = side0;
        this.side1 = side1;
        this.side2 = side2;
    }

    public Triangle.Type getTriangleType() {
        return Triangle.getTriangleType(side0, side1, side2);
    }

    public static Triangle.Type getTriangleType(double side0, double side1, double side2) {
        if (isEquilateral(side0, side1, side2)) {
            return Type.EQUILATERAL;
        } else if (isIsosceles(side0, side1, side2)) {
            return Type.ISOSCELES;
        } else if (isScalene(side0, side1, side2)) {
            return Type.SCALENE;
        } else {
            return Type.INVALID;
        }
    }

    private static boolean isScalene(double side0, double side1, double side2) {
        return side0 != side1 && side1 != side2;
    }

    private static boolean isIsosceles(double side0, double side1, double side2) {
        return side0 == side1 || side0 == side2 || side1 == side2;
    }

    private static boolean isEquilateral(double side0, double side1, double side2) {
        return side0 == side1 && side1 == side2;
    }

    public enum Type {
        EQUILATERAL,
        ISOSCELES,
        SCALENE,
        INVALID
    }
}

Hope this helps.

Note that I return the answer from the Triangles class instead of writing it out immidiately. And only in the manual run I write it out from the main method.