Search code examples
javaunit-testingjunitjunit5

Parameterized test using custom objects


I am trying to write a Parameterized test for my add method for Binary Search tree I wrote the test method:

void add() {
    student5 =  new Student("student5", LocalDate.of(2000,5,12), "none");
    studentSet2.add(student5);
    assertAll(
            ()->assertThat(studentSet2).contains(student5),
            ()->assertThat(studentSet2).hasSize(1),
            ()->assertThat(studentSet2.iterator().next()).isEqualTo(student5),
            ()->assertThat(studentSet2.toArray(new Student[1])).containsOnly(student5)
    );

This is my current test method but i want to transform it using parameterized test.But when i started to learn about it ,i found that he can take only strings and primitiv types. Can i write something for my test method to take a "Student" object as parameter?


Solution

  • You want create a lot of synthetic cases (or read from somewhere...), for example

    static Stream<Arguments> testAddToAListSource() {
        final List<String> baseData = List.of("one", "two", "three");
        
        // construct cases using a base list and adding null or a new element
        return IntStream.range(0, baseData.size() + 1)
                .mapToObj(n -> baseData.stream().limit(n).collect(toList()))
                .flatMap(xs -> Stream.of(null, "extra", "superExtra")
                    .map(x -> arguments(new ArrayList<>(xs), x)));
    }
    

    this method create pairs of a list of strings and a new string to add.

    Suppose you want to verify that this element is correctly added to the list checking the following invariants

    @ParameterizedTest
    @MethodSource("testAddToAListSource")
    void testAddToAList(List<String> caseList, String newElement) {
    
        // count elements
        final long currentSize = caseList.size();
    
        // count how many times the element is in list
        final long currentTimes = caseList.stream().filter(e -> Objects.equals(e, newElement)).count();
    
        // add
        caseList.add(newElement);
    
        // count elements
        final long newSize = caseList.size();
    
        // count how many times the element is in list
        final long newTimes = caseList.stream().filter(e -> Objects.equals(e, newElement)).count();
    
        assertEquals(newSize, currentSize + 1);
        assertEquals(newTimes, currentTimes + 1);
    }
    

    with output

    enter image description here

    in your specific case I don't know what type is studentSet2 but probably you could change your add signature to

    @ParameterizedTest
    @MethodSource("testAdd")
    void add(StudentSet studentSet2, Student student5) {
        ...
    

    and create a provider like

    static Stream<Arguments> testAdd() {
        ...