반응형

공통 코드

ProductService가 ProductRepository에 의존하고 있고, 테스트에서는 ProductRepository를 Mocking
public class ProductRepository {
    private static final Map<String, Integer> PRICE_MAP = Map.of(
        "keyboard", 1000,
        "mouse", 200
    );

    public int getPrice(String productName) {
        return PRICE_MAP.getOrDefault(productName, 0);
    }
}
@RequiredArgsConstructor
public class ProductService {
    private final ProductRepository productRepository;

    public int getPrice(String name) {
        return productRepository.getPrice(name);
    }
}

Basic

import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class MockitoBasicTest {
    @Test
    public void test() {
        ProductRepository productRepository = mock(ProductRepository.class);
        ProductService productService = new ProductService(productRepository);

        when(productRepository.getPrice("keyboard")).thenReturn(1);
        when(productRepository.getPrice("mouse")).thenReturn(2);

        assertEquals(1, productService.getPrice("keyboard"));
        assertEquals(2, productService.getPrice("mouse"));
    }
}

MockitoExtension

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class MockitoExtensionTest {
    @InjectMocks
    private ProductService productService;

    @Mock
    private ProductRepository productRepository;

    @Test
    public void test() {
        when(productRepository.getPrice("keyboard")).thenReturn(1);
        when(productRepository.getPrice("mouse")).thenReturn(2);

        assertEquals(1, productService.getPrice("keyboard"));
        assertEquals(2, productService.getPrice("mouse"));
    }
}

Verify

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class MockitoVerifyingTest {
    @InjectMocks
    private ProductService productService;

    @Mock
    private ProductRepository productRepository;

    @Test
    public void test() {
        when(productRepository.getPrice("keyboard")).thenReturn(1);

        assertEquals(1, productService.getPrice("keyboard"));
        assertEquals(1, productService.getPrice("keyboard"));

        verify(productRepository, times(2)).getPrice("keyboard");
        verify(productRepository, atLeast(1)).getPrice("keyboard");
        verify(productRepository, atLeastOnce()).getPrice("keyboard");
        verify(productRepository, atMost(3)).getPrice("keyboard");
        verify(productRepository, never()).getPrice("mouse");
    }
}

Exception

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.doThrow;

@ExtendWith(MockitoExtension.class)
public class MockitoExceptionTest {
    @InjectMocks
    private ProductService productService;

    @Mock
    private ProductRepository productRepository;

    @Test
    public void test() {
        doThrow(new IllegalStateException("TEST")).when(productRepository).getPrice("keyboard");

        assertThrows(IllegalStateException.class, () -> productService.getPrice("keyboard"));
    }
}

Answer

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import java.lang.reflect.Method;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class MockitoAnswerTest {
    @InjectMocks
    private ProductService productService;

    @Mock
    private ProductRepository productRepository;

    @Test
    public void test() {
        when(productRepository.getPrice("keyboard")).thenAnswer(invocation -> {
            Object[] args = invocation.getArguments();
            String productName = (String) args[0];
            ProductRepository productRepository = (ProductRepository) invocation.getMock();
            Method method = invocation.getMethod();

            System.out.printf("%s %s %s%n", productRepository, method.getName(), productName); // productRepository getPrice keyboard

            return 1;
        });

        assertEquals(1, productService.getPrice("keyboard"));
    }
}

Spy

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;

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

@ExtendWith(MockitoExtension.class)
public class MockitoSpyTest {
    @InjectMocks
    private ProductService productService;

    @Spy
    private ProductRepository productRepository; // final class, anonymouse classes, primitive types는 안됨

    @Test
    public void test() {
        assertEquals(1000, productService.getPrice("keyboard"));
        assertEquals(200, productService.getPrice("mouse"));
    }
}

BDD(Behavior Driven Development)

Behavior Driven Development is a style of writing tests uses given, when and then format as test methods.
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.BDDMockito.given;

@ExtendWith(MockitoExtension.class)
public class MockitoBDDTest {
    @InjectMocks
    private ProductService productService;

    @Mock
    private ProductRepository productRepository;

    @Test
    public void test() {
        given(productRepository.getPrice("keyboard")).willReturn(1);
        given(productRepository.getPrice("mouse")).willReturn(2);

        assertEquals(1, productService.getPrice("keyboard"));
        assertEquals(2, productService.getPrice("mouse"));
    }
}

참고

반응형

'Development > Java' 카테고리의 다른 글

[Java] Snowflake  (0) 2023.11.02
[Java] Java 소스 파일 컴파일하여 Class 객체로 로딩하기  (0) 2023.05.27
[Java] Random  (0) 2022.06.21
[Java] Cipher(RSA, AES)  (0) 2022.04.27
[Java] Base64  (0) 2022.04.26

+ Recent posts