아래의 코드와 같이 무작위 숫자에 대해서 알맞은 Boolean을 출력해주는 함수를 테스트 하는 경우를 생각해보았다. 원래 같은 경우라면 Mock을 이용해서 randomNumber.generate가 항상 4 가 나오도록 테스트를 했을 것이다. 하지만 과제의 특성상 Mock을 사용할 수 없었다.

스크린샷 2024-10-26 오후 5.48.52.png

이에 따라서 람다식으로 이부분을 대체할 수 있었다.

 @Test
    @DisplayName("랜덤값이 4이상이면 움직인다")
    void CanGoCase() {
        //given
        RandomMovement randomMovement = new RandomMovementGenerator(() -> 4);

        //when
        boolean result = randomMovement.canGo();

        //then
        assertThat(result).isTrue();
    }

    @Test
    @DisplayName("랜덤값이 3 이하면 안움직인다")
    void CantGoCase() {
        //given
        RandomMovement randomMovement = new RandomMovementGenerator(() -> 3);

        //when
        boolean result = randomMovement.canGo();

        //then
        assertThat(result).isFalse();
    }

<aside> 💡

간단한 의존성 주입을 하는 경우에 한해서 람다를 이용해서 테스트를 할 수 있다.

의존성 주입을 활용한 테스트는 특히 간단한 로직이거나 특정 상태나 값을 주입해야 하는 경우에 유용합니다. 이를 통해 외부 라이브러리 없이도 특정 상황을 시뮬레이션할 수 있어서 테스트 코드가 더 간결해지고, 실제 객체와의 상호작용을 자연스럽게 유지할 수 있어요. 많은 경우에 간단한 람다나 함수형 인터페이스로 대체할 수 있지만, 복잡한 로직이 요구되는 상황에서는 여전히 Mock 객체가 더 유리할 때도 있습니다.

</aside>

❗조금더 복잡한 Mock 의 stub 같은 람다식을 사용해보자.

스크린샷 2024-10-28 오후 6.29.45.png

여기서 AtomicInteger은 동시성 제어 도구이다.

AtomicIntegerJava의 동시성 지원 클래스로, 여러 스레드가 동시에 접근할 수 있는 스레드 안전한 정수형 변수입니다. AtomicInteger원자적(atomic) 연산을 제공하므로, 여러 스레드가 동시에 접근하더라도 값이 일관성을 유지하며 안전하게 증가하거나 감소할 수 있습니다.

코드에서 AtomicInteger의 역할

아래 코드에서 AtomicIntegercount 변수가 여러 번 호출될 때 증가 값을 안전하게 추적하도록 돕습니다.


AtomicInteger count = new AtomicInteger(0);
cars.playOneRound(() -> {
    int callCount = count.getAndIncrement();
    return (callCount == 1 || callCount == 2);
});

이 코드에서 AtomicInteger의 주요 역할은 호출 시마다 증가된 값(callCount)을 안전하게 가져오는 것입니다. 이때, getAndIncrement() 메서드는 현재 값을 반환한 후 원자적으로 1을 증가시키는 역할을 하며, 이 연산은 동시성 문제 없이 안전하게 이루어집니다.