본문 바로가기
Programming/JAVA

[java/IntelliJ/testng] Mapper 테스트 오류

by Pendine 2025. 1. 12.
728x90

 

https://plz-exception.tistory.com/28

 

Spring Boot (1) MybatisTest를 통한 Mapper 단위 테스트

개발 환경 : JAVA 1.8 / Spring Boot 2.4.1 / Gradle 6.7.1 / MySql IDE : IntelliJ 20.3.3 Dependency : mybatis-spring-boot-starter-test 2.1.3 * 해당 포스팅은 공식문서를 참조하여 작성했습니다. mybatis Test 공식문서 링크 1. 필요

plz-exception.tistory.com

않이이개외않되? Nullsector_1

님 블로그 에서 mybatis springboot test 공식문서 url 확인

 

구글에서 영어로 검색해도 한국어문서만 뜨는데

모든언어로 검색해도 내가 접속한 나라의 도메인을 우선으로 알려주는것같음

 

이번에 생각난김에 google.com 에 접속해서 하단의 설정 -> 검색 -> 지역을 미국으로 바꿔주도록 하자

 

 

1. 구글 메인페이지 접속. google.com

 

 

2. 설정클릭 -> "검색 설정" 클릭

 

3. 좌측 '기타 설정' 탭 클릭 후 언어 탭의 '언어 및 지역' 클릭

 

4. 검색결과 언어 및 지역 설정

영어+한국어 일때
왼쪽이 영어 + 한국어
오른쪽이 한국어

 

굿

 

일단 공식문서 참조해서

그래들 종속성 추가하기

dependencies {
    testImplementation("org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.4")
}

 

Jetbrain (IntelliJ 공식문서)

https://www.jetbrains.com/help/idea/testng.html#run-testng-with-reports

 

TestNG | IntelliJ IDEA

 

www.jetbrains.com

TestNG 빌드시 TestNG 빌드버전 참조

https://testng.org/#_testng_idea_plug_in

 

TestNG Documentation

This boolean specifies the way that class names are generated for the element. For example, * you will get for` false and * for true.

testng.org

TestNG 버전 번경(7.7.0 -> 7.9.0)

dependencies {
	testImplementation 'org.testng:testng:7.9.0'
}

 

 

이전문제

SelectMapper 클래스를 @Autowired 로 주입하려고해도 

Autowired members must be defined in valid Spring bean (@Component|@Service|...) 

해당 필드 멤버에 필요한 어노테이션이 없다고 에러나왔음

 

이문제를 해결하려고

테스트 클래스에서 사용했었으나 별개였었음.

@MapperScan(basePackages = "com.project.mapper")
@ComponentScan(basePackages = "com.project.mapper")
public class SelectMapperTest {

    @Autowired
    SelectMapper selectMapper;

	...
}

 

이렇게 붙이자

@MybatisTest
public class SelectMapperTest {

	@Autowired
	SelectMapper selectMapper;

	...
}

 

Could not autowire. No beans of 'SelectMapper' type found.

이런식으로 나옴

 

 

 

https://youtrack.jetbrains.com/issue/IDEA-205418/MyBatis-Mapper-bean-can-not-be-recognized

구글링으로 찾아보니  xml구성방식을 지원하지 않는다고 나온다

질문은 2019년도에, 답변은 2020년도에 달렸는데 2024년버전 IDEA 에서도 동일한 내용이 나오는걸 봐서는

현재도 지원되지 않는다고 봐도 될 듯 하다

 

추가적으로 찾아보니 실제로 xml 구성방식을 이용해서 데이터가 삽입, 삭제, 호출 등이 되는지 확인하기위해서라면

통합테스트 방식으로 진행해야하는 것 같다

 

일단 실DB에서 쿼리가 제대로 돼는지 확인하기위해서

https://www.geeksforgeeks.org/database-testing-using-java-selenium-and-testng/

 

Database Testing Using Java Selenium and TestNG - GeeksforGeeks

A Computer Science portal for geeks. It contains well written, well thought and well explained computer science and programming articles, quizzes and practice/competitive programming/company interview Questions.

www.geeksforgeeks.org

를 따라 그대로 가져다 사용했다. 

package com.project.mapper;

import com.project.component.UserComponent;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.context.annotation.ComponentScan;
import org.testng.Assert;

import org.mybatis.spring.boot.test.autoconfigure.MybatisTest;

import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.sql.*;
import java.util.List;


@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@MybatisTest
public class SelectMapperTest {

//    @Autowired
//    SelectMapper selectMapper;


    private Connection connection;
    private Statement statement;
    private ResultSet resultSet;

    @BeforeClass
    public void dbConnection() throws ClassNotFoundException, SQLException {
        // Database connection details
        String databaseURL = "jdbc:postgresql://localhost:5432/DB명?useUnicode=true&characterEncoding=utf8";
        String user = "admin";
        String password = "0000";

        // Load the MySQL JDBC driver and establish connection
        Class.forName("org.postgresql.Driver");
        System.out.println("Connecting to Database");
        connection = DriverManager.getConnection(databaseURL, user, password);

        // Check if the connection is successful
        if (connection == null) {
            System.out.println("Database Connection Failed");
        }else {
            System.out.println("Database Connection Successful");
        }
    }


    @Test
    public void testSelectUserById() {
        try {
            String query = "SELECT user_index,id,password,user_description FROM 스키마명.테이블명 WHERE user_index=1";
            statement = connection.createStatement();
            resultSet = statement.executeQuery(query);

            while( resultSet.next()){
                long idx = resultSet.getLong("user_index");
                String id = resultSet.getString("id");
                String name = resultSet.getString("user_description");
                String pw = resultSet.getString("password");
                System.out.println( idx + " , "
                                    + id + " , "
                                    + name + " , "
                                    + pw + " . "
                );
            }
//            UserComponent user = selectMapper.test_selectUserByIndex(3);
//            Assert.assertNotNull(user
//                                 , "User should not be null / userInfo : " + user.toString());

        } catch (Exception error) {
            error.printStackTrace();
        }
    }


    @AfterClass
    public void closeDatabaseConnection() {

        // Close the database connection
        if (connection != null) {
            try {
                System.out.println("Closing Database Connection...");
                connection.close();
            } catch (Exception error) {
                error.printStackTrace();
            }
        }
    }
}

 

 

dbDriver와 @BeforeClass 이용해서 db접속을하고

@Test 에서 쿼리 날린후

@AfterClass에서 db접속을 종료하는것으로 완료.

 

 

데이터 쿼리가 정상적으로 수행돼는것을 확인했으나......

 

 

발견한 postgres 사용시 문제점

 

1. 기본적으로 postgres는 sql 사용시 모든 쿼리문을 소문자로 바꿔서 수행한다.

따라서 기본적으로 모든 명칭을 소문자로 작성해야한다. (스키마, 테이블, 컬럼)

2. postgres는 스키마라를 일반적인 DB의 스키마와 별개의 개념으로 사용한다.

일반적으로 스키마란 DB의 전체적인 구조를 의미하지만.

postgres에서는 하나의 DB에 여러개의 스키마가 존재할 수 있다.

  각각의 DB에 하나의 스키마가 있는게 아니라 여러개의 스키마가 존재할 수 있다.

  하나의 스키마에는 동일한 테이블 이름이 존재할수 없으나 다른 스키마에는 동일한 이름의 테이블이 존재할 수 있다.

  A라는 이름의 데이터베이스에 B라는 스키마와 C라는 스키마가 존재할 수 있고, 두 스키마는 동일하게 T라는 테이블명이 존재할 수 있다.

  서로다른 스키마의 테이블을 참조하여 외래키로 사용할수도 있다

3. 기본적으로 스키마를 지정하여 쿼리를 하지 않는경우에는 기본생성되는 public이라는 사용함.

 

 

 

이번에 테스트로 에러가 발생했던 아래의 쿼리였다.

 

SELECT *

FROM "AssetsManageMent".USER;
WHERE user_index = 1

 

 

"쿼리문의 모든 내용은 소문자로 치환" 하는것이었는데

나는 "쿼리문의 컬럼명만 소문자"로 사용하는것이라 기억하고 있었기 때문에

컬럼명만 소문자 및 스네이크 명명식으로 변경해줬기 때문에 제대로 수행할 것이라고 판단해서 발생했던 에러다

오늘로 스키마와 테이블명을 전부 스네이크 및 소문자명으로 치환했다.

 

 

하나 만들어보면서 덕분에 여러모로 알아가는중.

아니 잠깐만 Mapper 인터페이스로 테스트는 해보지도 못했네...

728x90

댓글