본문 바로가기
개발 - Coding/Algorithm

Junit assertArrayEquals를 이용하여 array 비교하기

by dev_jinyeong 2022. 7. 21.

java array 비교하기

Junit을 이용해서 결과를 테스트하다보면, array를 비교해야 할 경우가 생긴다.

이런 경우에 단순히 assertEquals 메서드를 이용해서 비교하면 테스트에 실패한다.

두 array가 다른 객체이기 때문에 다른 메모리 주소를 참조하기 때문이다.

예시

프로그래머스에서 간단한 행렬의 덧셈 문제를 풀고, Junit으로 검증해보겠다.

행렬의 덧셈 문제

// 내가 작성한 답
public class Solution {
    public int[][] solution(int[][] arr1, int[][] arr2) {
        int outerLength = arr1.length;
        int innerLength = arr1[0].length;
        int[][] answer = new int[outerLength][innerLength];

        for(int i=0; i<outerLength; i++){
            for(int j=0; j<innerLength; j++){
                answer[i][j] = arr1[i][j] + arr2[i][j];
            }
        }

        return answer;
    }
}
// 내가 작성한 테스트 코드
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class SolutionTest {

    Solution solution = new Solution();

    @Test
    public void testcase_basic(){
        int[][] arr1 = {{1,2},{2,3}};
        int[][] arr2 = {{3,4},{5,6}};
        int[][] expected = {{4,6}, {7,9}};
        assertEquals(solution.solution(arr1, arr2), expected);
    }
}

테스트 실패

실패 케이스를 자세히 보면, [[4, 6], [7, 9]]로 두 array의 값은 동일한 것을 알 수 있다.

그러나 서로 다른 객체이기 때문에 테스트가 실패하고 있다.

이런 경우에는 array를 어떻게 비교하면 좋을까?

assertArrayEquals 메소드 활용하기

// 새로 작성한 테스트 코드
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import java.util.Arrays;

import static org.junit.jupiter.api.Assertions.*;

class SolutionTest {

    Solution solution = new Solution();

    @Test
    public void testcase_basic(){
        int[][] arr1 = {{1,2},{2,3}};
        int[][] arr2 = {{3,4},{5,6}};
        int[][] expected = {{4,6}, {7,9}};
        assertArrayEquals(solution.solution(arr1, arr2), expected);
    }
}

Junit에서는 array를 비교하기 위한 assertArrayEquals 메소드를 제공하고 있으므로 이를 이용하면 된다.

이를 이용해서 테스트를 실행할 경우 성공하는 것을 확인할 수 있다.

assertArrayEquals 메소드의 동작원리

// assertArrayEquals 동작원리
private static void assertArrayEquals(Object[] expected, Object[] actual, Deque<Integer> indexes, Object messageOrSupplier) {
        if (expected != actual) {
            assertArraysNotNull(expected, actual, indexes, messageOrSupplier);
            assertArraysHaveSameLength(expected.length, actual.length, indexes, messageOrSupplier);

            for(int i = 0; i < expected.length; ++i) {
                Object expectedElement = expected[i];
                Object actualElement = actual[i];
                if (expectedElement != actualElement) {
                    indexes.addLast(i);
                    assertArrayElementsEqual(expectedElement, actualElement, indexes, messageOrSupplier);
                    indexes.removeLast();
                }
            }

        }
    }

assertArrayEquals 메소드는

1. 두 array가 같은 객체인지 검사하고

2. 같은 객체가 아니라면 Null이 아닌지 검사하고

3. 같은 길이를 가진 array인지 검사하고

4. Null도 아니고 같은 길이를 가지고 있다면 요소를 하나씩 검사하는 로직을 가지고 있다.

내부 동작 자체는 복잡하게 구현되어 있지 않으므로 쉽게 이해할 수 있다.