모킹에서의 검증

Java 테스트 소개

Maria Milusheva

Senior Software Engineer

동기: 반환값 없음

이전 레슨과 연습에서는 반환값을 기준으로 테스트했습니다.

  • 하지만 반환값이 없으면 어떻게 할까요?

  • 반환값이 중요하지 않거나 유용하지 않다면요?

예: 데이터베이스에 저장.

파일이 저장되는 데이터베이스 그래픽

Java 테스트 소개

예시: 데이터베이스

데이터베이스: 구조화된 데이터를 저장·관리·보호하는 디지털 저장소입니다. 제공자가 다양합니다: 일부 인기 데이터베이스 로고

  • 데이터베이스 서버는 내구성, 보안성, 신뢰성이 높고 용량이 사실상 무제한입니다

  • 실제 데이터베이스는 단위 테스트에는 너무 크고 복잡합니다(통합 테스트에서는 사용 가능)

Java 테스트 소개

예시: 로그 메시지

로그를 처리한다고 가정해 봅시다:

public class MessageProcessor {
    private InfoStore infoStore;  // Will store info log messages here
    private ErrorStore errorStore; // Will store error log messages here

    public void saveMessage(String message) {
        if (message.startsWith("[INFO]")) {
            infoStore.save(message);
        }
        if (message.startsWith("[ERROR]")) {
            errorStore.save(message);
        }
    }
}
Java 테스트 소개

InfoStore와 ErrorStore

테스트에는 기본 인터페이스만 있으면 됩니다:

// Blueprints for InfoStore and ErrorStore
// Mocks don't need the mocked classes to be properly implemented
interface InfoStore {
    void save(String message);
}

interface ErrorStore {
    void save(String message);
}
Java 테스트 소개

Mockito verify

데이터베이스를 만들지 않고 메시지가 저장됐는지 어떻게 테스트할까요?

모크가 호출되었는지 검증:

import static org.mockito.Mockito.verify;

모크가 호출되지 않았는지 검증:

import static org.mockito.Mockito.verifyNoInteractions;
Java 테스트 소개

테스트 설정

@Test
void process_savesToInfoStore_whenInfoMessage() {
  InfoStore infoStore = mock(InfoStore.class);
  ErrorStore errorStore = mock(ErrorStore.class);
  MessageProcessor messageProcessor = new MessageProcessor(infoStore, errorStore);

String message = "[INFO] Process started."; messageProcessor.saveMessage(message); // Will use either InfoStore or ErrorStore
// Verify which one of the two databases was used verify(infoStore).save(message); verifyNoInteractions(errorStore); }
Java 테스트 소개

테스트 실패 메시지

만약 우리가 만드는 메시지가 다음과 같다면:

String message = "[ERROR] Process failed!"

다음과 같은 테스트 실패가 발생합니다:

Wanted but not invoked:
infoStore.save("[ERROR] Process failed!");
Actually, there were zero interactions with this mock.
Java 테스트 소개

추가 검증 기법

로그가 몇 번 호출되었는지 정확히 검증할 수 있습니다:

import static org.mockito.Mockito.times;
List<String> messages = new ArrayList<>(); // Create list and add elements
                messages.add("[INFO] Processing data...");
                messages.add("[INFO] Processing data...");
                messages.add("[INFO] Processing data...");

messageProcessor.saveMessageList(messages); // Save the three messages


verify(infoStore, times(3)).save("[INFO] Processing data...");
Java 테스트 소개

연습해 봅시다!

Java 테스트 소개

Preparing Video For Download...