아래의 코드와 같이 무작위 숫자에 대해서 알맞은 Boolean을 출력해주는 함수를 테스트 하는 경우를 생각해보았다. 원래 같은 경우라면 Mock을 이용해서 randomNumber.generate가 항상 4 가 나오도록 테스트를 했을 것이다. 하지만 과제의 특성상 Mock을 사용할 수 없었다.
이에 따라서 람다식으로 이부분을 대체할 수 있었다.
@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>
여기서 AtomicInteger은 동시성 제어 도구이다.
AtomicInteger
는 Java의 동시성 지원 클래스로, 여러 스레드가 동시에 접근할 수 있는 스레드 안전한 정수형 변수입니다. AtomicInteger
는 원자적(atomic) 연산을 제공하므로, 여러 스레드가 동시에 접근하더라도 값이 일관성을 유지하며 안전하게 증가하거나 감소할 수 있습니다.
AtomicInteger
의 역할아래 코드에서 AtomicInteger
는 count
변수가 여러 번 호출될 때 증가 값을 안전하게 추적하도록 돕습니다.
AtomicInteger count = new AtomicInteger(0);
cars.playOneRound(() -> {
int callCount = count.getAndIncrement();
return (callCount == 1 || callCount == 2);
});
이 코드에서 AtomicInteger
의 주요 역할은 호출 시마다 증가된 값(callCount
)을 안전하게 가져오는 것입니다. 이때, getAndIncrement()
메서드는 현재 값을 반환한 후 원자적으로 1을 증가시키는 역할을 하며, 이 연산은 동시성 문제 없이 안전하게 이루어집니다.