Notice
Recent Posts
Recent Comments
Link
«   2025/04   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
Archives
Today
Total
관리 메뉴

전공공부

Mockito를 사용한 단위 테스트에서 발생하는 다양한 이슈 본문

Study/Spring Boot

Mockito를 사용한 단위 테스트에서 발생하는 다양한 이슈

monitor 2024. 1. 20. 22:15

단위 테스트는 소프트웨어 개발의 중요한 부분입니다. Mockito는 Java에서 단위 테스트를 작성할 때 널리 사용되는 프레임워크 중 하나입니다. 하지만 Mockito를 사용하면서 발생할 수 있는 몇 가지 이슈가 있었고 이를 정리해봤습니다.

문제 : NullPointerException / MockitoException
Cannot invoke "org.springframework.jdbc.core.JdbcTemplate.queryForObject(String, Object[], org.springframework.jdbc.core.RowMapper)" because "this.jdbcTemplate" is null

 

이 에러는 UserDaoImpl 클래스의 인스턴스가 생성될 때 JdbcTemplate 객체가 주입되지 않아서 발생합니다. UserDaoTest 클래스에서 UserDaoImpl 객체를 생성할 때 JdbcTemplate 객체를 주입해야 합니다.

org.mockito.exceptions.base.MockitoException: 
Cannot instantiate @InjectMocks field named 'userDao'! Cause: the type 'UserDao' is an interface.

 

이 에러는 @InjectMocks 어노테이션이 붙은 필드가 인터페이스 타입이기 때문에 발생합니다. Mockito는 인터페이스의 인스턴스를 생성할 수 없습니다. 따라서 구현체를 불러와서 해결해봅시다.

 

해결 방법

 

테스트 클래스를 아래와 같이 수정합니다:

@ExtendWith(MockitoExtension.class)
public class UserDaoTest {

    @Mock
    private JdbcTemplate jdbcTemplate;

    private UserDao userDao;

    @BeforeEach
    public void setUp() {
        userDao = new UserDaoImpl(jdbcTemplate);
    }

    @Test
    public void testUserDao() {
        when(jdbcTemplate.queryForObject(anyString(), any(Object[].class), any(RowMapper.class)))
                .thenReturn(new User(1L, "John Doe"));

        User retrievedUser = userDao.getUserById(1L);

        assertThat(retrievedUser).isNotNull();
        assertThat(retrievedUser.getName()).isEqualTo("John Doe");
    }
}

 

 

@BeforeEach 어노테이션이 붙은 setUp 메소드는 각 테스트 메소드가 실행되기 전에 호출됩니다. 이 메소드에서 UserDaoImpl 객체를 생성하고 JdbcTemplate 객체를 주입하고 있습니다. 이렇게 하면 UserDaoImpl 클래스의 메소드를 호출할 때 NullPointerException이 발생하지 않을 것입니다.

 

@InjectMocks 어노테이션이 제거되었고, UserDao 필드가 UserDaoImpl 타입으로 변경되었습니다. 이렇게 하면 Mockito가 UserDaoImpl 인스턴스를 생성할 수 있습니다.

 

간단하지만 사실 이런 에러가 왜 생기고 이를 어떻게 처리 할 지에 대해서 상세히 정리해봤습니다. 물론, SpringBootTest를 쓰고 의존성을 추가하면 되지만 그것은 진정한 의미의 단위 테스트가 될 수 없다고 생각합니다. 따라서, 이런 방식을 참고해서 앞으로 테스트 케이스의 작성을 고급지게 할 수 있을 것 입니다.

 

코드 링크

https://github.com/1ComputerMaster/1ComputerMaster/tree/main/Study/tester