<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Spring on 의찬의 개발 블로그</title><link>https://uechann.github.io/categories/spring/</link><description>Recent content in Spring on 의찬의 개발 블로그</description><generator>Hugo</generator><language>ko-kr</language><lastBuildDate>Tue, 23 Jun 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://uechann.github.io/categories/spring/index.xml" rel="self" type="application/rss+xml"/><item><title>스프링 빈의 설계 철학</title><link>https://uechann.github.io/posts/spring/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88%EC%9D%98-%EC%84%A4%EA%B3%84-%EC%B2%A0%ED%95%99/</link><pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88%EC%9D%98-%EC%84%A4%EA%B3%84-%EC%B2%A0%ED%95%99/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;h3 id="스프링-빈의-설계-철학"&gt;스프링 빈의 설계 철학&lt;/h3&gt;
&lt;p&gt;스프링 빈은 객체 생성, 조립, 생명주기의 통제권을 객체가 아니라 외부 컨테이너로 옮긴 결과물이고,
통제권의 이전의 목적은 DIP 의존성 역적 원칙을
코드가 아니라 인프라 수준에서 강제하여 결합도를 낮추는 것이다.&lt;/p&gt;</description></item><item><title>톰캣과 스레드 모델</title><link>https://uechann.github.io/posts/spring/%ED%86%B0%EC%BA%A3%EA%B3%BC-%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%AA%A8%EB%8D%B8/</link><pubDate>Tue, 23 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/%ED%86%B0%EC%BA%A3%EA%B3%BC-%EC%8A%A4%EB%A0%88%EB%93%9C-%EB%AA%A8%EB%8D%B8/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;p&gt;먼저 전체적인 요청에 대한 흐름 그림은 다음과 같다.&lt;/p&gt;
&lt;p&gt;&lt;img src="img-8bf7077e83.png" alt=""&gt;&lt;/p&gt;
&lt;h3 id="톰캣-스레드-모델과-커넥션-풀까지"&gt;톰캣 스레드 모델과 커넥션 풀까지&lt;/h3&gt;
&lt;p&gt;요청1개가 들어왔을 때 어디서 스레드를 받아 처리되고 어떻게 반환이 되는지,
그 스레드가 DB 커넥션과 어떻게 연결이 되는지 이해한다.&lt;/p&gt;</description></item><item><title>TPS와 Rate Limit 대응</title><link>https://uechann.github.io/posts/spring/tps%EC%99%80-rate-limit-%EB%8C%80%EC%9D%91/</link><pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/tps%EC%99%80-rate-limit-%EB%8C%80%EC%9D%91/</guid><description>&lt;p&gt;Rate Limit는 초당 N건이라는 정책을 토큰 버킷 하나로 구현을하고,
같은 알고리즘으로 들어오는 요청과 나가는 호출에 방향만 바꿔서 적용하는 것이다.&lt;/p&gt;
&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;p&gt;AI를 이용해 핵심 개념을 빠르게 파악한다.
깊은 이해보다는 새로운 기술이 어떤 기술인지 어떤 문제를 해결하기 위해 등장했는지 지도만 그린다.
공식문서 docs를 기반으로 신뢰 있는 개념 정보를 추출한다.&lt;/p&gt;</description></item><item><title>외부 API 호출 방식</title><link>https://uechann.github.io/posts/spring/%EC%99%B8%EB%B6%80-api-%ED%98%B8%EC%B6%9C-%EB%B0%A9%EC%8B%9D/</link><pubDate>Tue, 16 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/%EC%99%B8%EB%B6%80-api-%ED%98%B8%EC%B6%9C-%EB%B0%A9%EC%8B%9D/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;h3 id="결론"&gt;결론&lt;/h3&gt;
&lt;p&gt;외부 API 호출 구현 방식&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;새 프로젝트라면 단순 호출은 &lt;code&gt;RestClient&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;여러 엔드포인트를 인터페이스로 묶는다면 HTTP Interface(&lt;code&gt;@HttpExchange&lt;/code&gt;) + RestClient adapter,&lt;/li&gt;
&lt;li&gt;reactive 스택이면 &lt;code&gt;WebClient&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;RestTemplate&lt;/code&gt;은 2025-11에 deprecation 의도로 공지가 되었고 신규 코드에서는 쓰지 않는다고 한다.&lt;/p&gt;</description></item><item><title>테스트 코드가 왜 필요할까 ?</title><link>https://uechann.github.io/posts/spring/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C%EA%B0%80-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%A0%EA%B9%8C/</link><pubDate>Fri, 12 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C%EA%B0%80-%EC%99%9C-%ED%95%84%EC%9A%94%ED%95%A0%EA%B9%8C/</guid><description>&lt;p&gt;제가 생각 했던 테스트 코드들에 대해 생각했던 내용을 생각해보고 Kent Beck이 생각하는 테스트 코드에 대해서 찾아보고 정리 해보았습니다. 제가 지금까지 개발을 하면서 겪었던 경험을 토대로 한 저의 테스트 코드 필요성 Kent Beck이 생각하는 테스트 코드의 필요성을 접목하고 다음과 같이 정리해 보았습니다.&lt;/p&gt;</description></item><item><title>Spring MVC의 흐름</title><link>https://uechann.github.io/posts/spring/spring-mvc%EC%9D%98-%ED%9D%90%EB%A6%84/</link><pubDate>Thu, 11 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/spring-mvc%EC%9D%98-%ED%9D%90%EB%A6%84/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;h3 id="spring-mvc의-흐름"&gt;Spring MVC의 흐름&lt;/h3&gt;
&lt;p&gt;Spring MVC에서 핵심은 &lt;code&gt;DispatcherServlet&lt;/code&gt;을 기준으로 흐름을 보는게 중요하다고 생각합니다.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;요청 수신: &lt;code&gt;DispatcherServlet&lt;/code&gt;으로 클라이언트 요청이 들어온다.&lt;/li&gt;
&lt;li&gt;핸들러 조회: &lt;code&gt;HandlerMapping&lt;/code&gt;이 요청 url에 맞는 컨트롤러를 찾아준다.&lt;/li&gt;
&lt;li&gt;핸들러 실행: &lt;code&gt;HandlerAdapter&lt;/code&gt;가 해당 컨트롤러를 실행한다. 이때 &lt;code&gt;ArgumentResolver&lt;/code&gt;가 파라미터를 바인딩&lt;/li&gt;
&lt;li&gt;분기: 컨트롤러의 반환 형태에 따라 &lt;code&gt;ReturnValueHandler&lt;/code&gt;에 의해 분기 된다.&lt;/li&gt;
&lt;li&gt;뷰 처리: &lt;code&gt;ViewResolver&lt;/code&gt;가 뷰 이름을 실제 &lt;code&gt;View&lt;/code&gt;로 변환하고, &lt;code&gt;View&lt;/code&gt;가 모델을 렌더링한다.&lt;/li&gt;
&lt;li&gt;REST 경로: &lt;code&gt;HttpMessageConverter&lt;/code&gt;가 반환 객체를 JSON으로 직렬화후 body에 작성한다.&lt;/li&gt;
&lt;li&gt;응답 전송: 최종 렌더링 결과를 클라이언트에 응답한다.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;크게 이렇게 6개로 볼 수 있을거 같습니다.&lt;/p&gt;</description></item><item><title>DTO는 class + Lombok으로 만들까요, record로 만들까요?</title><link>https://uechann.github.io/posts/spring/dto%EB%8A%94-class-lombok%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B9%8C%EC%9A%94-record%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B9%8C%EC%9A%94/</link><pubDate>Fri, 05 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/dto%EB%8A%94-class-lombok%EC%9C%BC%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B9%8C%EC%9A%94-record%EB%A1%9C-%EB%A7%8C%EB%93%A4%EA%B9%8C%EC%9A%94/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;h3 id="dto는-class--lombok-vs-record"&gt;DTO는 class + Lombok vs record&lt;/h3&gt;
&lt;p&gt;JSON, 객체와의 변환을 만들기 위해서,
보일러플레이트를 줄이는 도구 Lombok class와 record 중에서 어떤 것을 사요할지에 대한 문제이다.&lt;/p&gt;
&lt;p&gt;둘다 @RequestBody로 받지만, Jackson이 객체를 만들어내는 경로 생성 방식이 다르다.&lt;/p&gt;</description></item><item><title>읽기 작업에 @Transactional(readonly = true)를 사용하는 이유</title><link>https://uechann.github.io/posts/spring/%EC%9D%BD%EA%B8%B0-%EC%9E%91%EC%97%85%EC%97%90-transactionalreadonly-true%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0/</link><pubDate>Wed, 03 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/%EC%9D%BD%EA%B8%B0-%EC%9E%91%EC%97%85%EC%97%90-transactionalreadonly-true%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94-%EC%9D%B4%EC%9C%A0/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;h3 id="transactionalreadonly--true"&gt;Transactional(readOnly = true)&lt;/h3&gt;
&lt;p&gt;@Transactional의 한 속성으로,
”이 트랜잭션 안에서는 데이터를 읽기만 하고 변경하지 않는다”라는 것을 선언한다.&lt;/p&gt;
&lt;p&gt;핵심은 강제가 아니라, 선언/힌트라는 점이다.&lt;/p&gt;</description></item><item><title>Repository와 DAO의 차이점</title><link>https://uechann.github.io/posts/spring/repository%EC%99%80-dao%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90/</link><pubDate>Tue, 02 Jun 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/repository%EC%99%80-dao%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;h2 id="dao란-data-access-object"&gt;DAO란 (Data Access Object)&lt;/h2&gt;
&lt;p&gt;데이터들을 &lt;code&gt;어떻게(how)&lt;/code&gt; 저장할지에 대해서 대답한다.&lt;/p&gt;
&lt;p&gt;데이터베이스에 접근해서 데이터를 가져오거나 저장하는 심부른꾼 전담 객체
비즈니스 로직과 데이터베이스 접근 로직을 철저하게 분리하기 위해서 사용한다.&lt;/p&gt;</description></item><item><title>ArgumentResolver와 ReturnValueHandler 란?</title><link>https://uechann.github.io/posts/spring/argumentresolver%EC%99%80-returnvaluehandler-%EB%9E%80/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/argumentresolver%EC%99%80-returnvaluehandler-%EB%9E%80/</guid><description>&lt;h2 id="어떤-개념인가요-"&gt;어떤 개념인가요 ?&lt;/h2&gt;
&lt;p&gt;Spring MVC에서 컨트롤러 메서드의 파라미터를 만들어주는 역할과 반환값을 처리해주는 역할을 담당하는 두개의 확장 포인트이다.&lt;/p&gt;
&lt;h2 id="어떤-문제를-해결하려고-나왔나"&gt;어떤 문제를 해결하려고 나왔나?&lt;/h2&gt;
&lt;p&gt;초기 Spring MVC는 시그니처가 정해져 있었다.&lt;/p&gt;</description></item><item><title>CGLIB와 프록시의 생성 방식은 어떻게 될까 ?</title><link>https://uechann.github.io/posts/spring/cglib%EC%99%80-%ED%94%84%EB%A1%9D%EC%8B%9C%EC%9D%98-%EC%83%9D%EC%84%B1-%EB%B0%A9%EC%8B%9D%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%90%A0%EA%B9%8C/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/cglib%EC%99%80-%ED%94%84%EB%A1%9D%EC%8B%9C%EC%9D%98-%EC%83%9D%EC%84%B1-%EB%B0%A9%EC%8B%9D%EC%9D%80-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%90%A0%EA%B9%8C/</guid><description>&lt;h2 id="어떤-개념인가요-"&gt;어떤 개념인가요 ?&lt;/h2&gt;
&lt;h3 id="proxy-프록시"&gt;Proxy 프록시&lt;/h3&gt;
&lt;p&gt;프록시란 원본 객체를 대신해서 앞에 서는 대리 객체이다.
클라이언트는 프록시를 원본인줄 알고 호출하고, 프록시가 중간에서 일을 수행하고 원본에 위임한다.&lt;/p&gt;</description></item><item><title>Filter와 Interceptor는 어떻게 작동될까</title><link>https://uechann.github.io/posts/spring/filter%EC%99%80-interceptor%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%91%EB%8F%99%EB%90%A0%EA%B9%8C/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/filter%EC%99%80-interceptor%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%9E%91%EB%8F%99%EB%90%A0%EA%B9%8C/</guid><description>&lt;h2 id="어떤-개념일까"&gt;어떤 개념일까?&lt;/h2&gt;
&lt;h3 id="filter-vs-interceptor"&gt;Filter vs Interceptor&lt;/h3&gt;
&lt;p&gt;둘은 둘다 요청을 가로채는 공통의 관심사 분리 도구이지만,
필터는 서블릿 컨테이너 레벨에서 DispatcherServlet &lt;code&gt;바깥&lt;/code&gt;을 감싸고,
인터셉터는 스프링 MVC 레벨에서 DispatcherServlet &lt;code&gt;안쪽&lt;/code&gt; 핸들러 호출 주변을 감싼다.
동작하는 위치가 다르기 때문에 할 수 있는 것과, 용도가 다르다.&lt;/p&gt;</description></item><item><title>JDBCTest</title><link>https://uechann.github.io/posts/spring/jdbctest/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/jdbctest/</guid><description>&lt;h2 id="어떤-개념인가요-"&gt;어떤 개념인가요 ?&lt;/h2&gt;
&lt;p&gt;JDBC 기반 컴포넌트만 격리해서 테스트하기 위한 Spring Boot의 슬라이스 테이스 어노테이션이다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;전체 애플리케이션을 띄우지 않고,&lt;br&gt;
JDBC 작업에 필요한 최소한의 것만 로드해서 테스트하는 것이 본질이다.&lt;/p&gt;</description></item><item><title>Mock이란 무엇인가?</title><link>https://uechann.github.io/posts/spring/mock%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/mock%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/</guid><description>&lt;h2 id="어떤-개념인가요-"&gt;어떤 개념인가요 ?&lt;/h2&gt;
&lt;h3 id="mock이란-무엇일까"&gt;Mock이란 무엇일까?&lt;/h3&gt;
&lt;p&gt;Mock은 테스트 대상이 의존하는 객체를 흉내내는 가짜 객체이다.&lt;/p&gt;
&lt;p&gt;실제 객체처럼 호출할 수 있지만, 내부 동작은 우리가 미리 정의한 대로만 응답하게 된다.&lt;/p&gt;</description></item><item><title>queryForObject 호출시 조회결과가 비어있으면
어떤 상황이 발생할까</title><link>https://uechann.github.io/posts/spring/queryforobject-%ED%98%B8%EC%B6%9C%EC%8B%9C-%EC%A1%B0%ED%9A%8C%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%B9%84%EC%96%B4%EC%9E%88%EC%9C%BC%EB%A9%B4-%EC%96%B4%EB%96%A4-%EC%83%81%ED%99%A9%EC%9D%B4-%EB%B0%9C%EC%83%9D%ED%95%A0%EA%B9%8C/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/queryforobject-%ED%98%B8%EC%B6%9C%EC%8B%9C-%EC%A1%B0%ED%9A%8C%EA%B2%B0%EA%B3%BC%EA%B0%80-%EB%B9%84%EC%96%B4%EC%9E%88%EC%9C%BC%EB%A9%B4-%EC%96%B4%EB%96%A4-%EC%83%81%ED%99%A9%EC%9D%B4-%EB%B0%9C%EC%83%9D%ED%95%A0%EA%B9%8C/</guid><description>&lt;h1 id="-의도적-파괴-학습-로그"&gt;💥 의도적 파괴 학습 로그&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;날짜:&lt;/strong&gt; YYYY-MM-DD&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;개념 / 대상 코드:&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id="어떤-개념인가요-"&gt;어떤 개념인가요 ?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;queryForObject&lt;/strong&gt;
는 SQL 조회 결과가 정확히 1건일 것을 기대하는 메서드입니다.
0건 또는 2건 이상이면 Spring이 예외를 던집니다. 이 동작을 직접 눈으로 확인합니다.&lt;/p&gt;</description></item><item><title>RestController vs Controller, ControllerAdvice, RestControllerAdvice, ExceptionHandler vs GlobalExceptionHandler</title><link>https://uechann.github.io/posts/spring/restcontroller-vs-controller-controlleradvice-restcontrolleradvice-exceptionhandler-vs-globalexceptionhandler/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/restcontroller-vs-controller-controlleradvice-restcontrolleradvice-exceptionhandler-vs-globalexceptionhandler/</guid><description>&lt;h2 id="어떤-개념인가요-"&gt;어떤 개념인가요 ?&lt;/h2&gt;
&lt;h3 id="controller-vs-restcontroller"&gt;Controller vs RestController&lt;/h3&gt;
&lt;p&gt;Controller는 Spring MVC 부터 있었고, 메서드가 반환하는 문자열을 View 이름으로 해석한다.&lt;/p&gt;
&lt;p&gt;즉, Server Side Rendering SSR 방식 서버가 직접 HTML을 만드는 전통적인 방식에서 사용한다.&lt;/p&gt;</description></item><item><title>Service 통합테스트를 작성한다면 Repository 테스트는 필요없을까요?</title><link>https://uechann.github.io/posts/spring/service-%ED%86%B5%ED%95%A9%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%9E%91%EC%84%B1%ED%95%9C%EB%8B%A4%EB%A9%B4-repository-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%8A%94-%ED%95%84%EC%9A%94%EC%97%86%EC%9D%84%EA%B9%8C%EC%9A%94/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/service-%ED%86%B5%ED%95%A9%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%A5%BC-%EC%9E%91%EC%84%B1%ED%95%9C%EB%8B%A4%EB%A9%B4-repository-%ED%85%8C%EC%8A%A4%ED%8A%B8%EB%8A%94-%ED%95%84%EC%9A%94%EC%97%86%EC%9D%84%EA%B9%8C%EC%9A%94/</guid><description>&lt;h2 id="어떤-개념인가요-"&gt;어떤 개념인가요 ?&lt;/h2&gt;
&lt;p&gt;테스트를 할 때 계층별로 기준을 어디서부터 어디까지 나눠야 할지에 대해서 항상 생각을 많이 하는거 같다.
이 중에서 Service 통합테스트에 대해서 생각을 해보려고 한다.
&lt;code&gt;Service 통합테스트를 작성한다면 Repository 테스트는 필요가 없을까?&lt;/code&gt; 에 대한 질문이다.&lt;/p&gt;</description></item><item><title>계층별 테스트 코드 작성 : 나만의 방법</title><link>https://uechann.github.io/posts/spring/%EA%B3%84%EC%B8%B5%EB%B3%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1-%EB%82%98%EB%A7%8C%EC%9D%98-%EB%B0%A9%EB%B2%95/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/%EA%B3%84%EC%B8%B5%EB%B3%84-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1-%EB%82%98%EB%A7%8C%EC%9D%98-%EB%B0%A9%EB%B2%95/</guid><description>&lt;h2 id="1-repository-계층"&gt;1. Repository 계층&lt;/h2&gt;
&lt;h3 id="무엇을-검증하는가"&gt;무엇을 검증하는가&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;직접 작성한 SQL/쿼리,&lt;/li&gt;
&lt;li&gt;컬럼↔객체 매핑(&lt;code&gt;RowMapper&lt;/code&gt;),&lt;/li&gt;
&lt;li&gt;DB 제약조건(unique·FK) 위반 시 기대한 예외.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="어떻게-테스트-할까"&gt;어떻게 테스트 할까&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@JdbcTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// JdbcTemplate 기반. JPA면 @DataJpaTest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ReservationRepositoryTest&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Autowired&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;JdbcTemplate&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;jdbcTemplate&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kt"&gt;void&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nf"&gt;중복_슬롯_저장시_제약조건_위반_예외가_발생한다&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="c1"&gt;// unique 제약을 가진 슬롯을 두 번 저장 → 기대한 예외 검증&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;dl&gt;
&lt;dt&gt;사용하는 기술에 따라서 다르게 접근한다.&lt;/dt&gt;
&lt;dd&gt;
&lt;p&gt;&lt;code&gt;@JdbcTest&lt;/code&gt; &lt;code&gt;@DataJpaTest&lt;/code&gt;, + 인메모리 H2 or Testcontainers&lt;/p&gt;</description></item><item><title>테스트 격리는 어떻게 보장해야 할까</title><link>https://uechann.github.io/posts/spring/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B2%A9%EB%A6%AC%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%B3%B4%EC%9E%A5%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C/</link><pubDate>Thu, 28 May 2026 00:00:00 +0000</pubDate><guid>https://uechann.github.io/posts/spring/%ED%85%8C%EC%8A%A4%ED%8A%B8-%EA%B2%A9%EB%A6%AC%EB%8A%94-%EC%96%B4%EB%96%BB%EA%B2%8C-%EB%B3%B4%EC%9E%A5%ED%95%B4%EC%95%BC-%ED%95%A0%EA%B9%8C/</guid><description>&lt;h2 id="테스트-격리란"&gt;테스트 격리란?&lt;/h2&gt;
&lt;h3 id="테스트-격리"&gt;테스트 격리&lt;/h3&gt;
&lt;p&gt;각 테스트가 다른 테스트의 상태에 영향을 주지도, 받지도 않게 만드는 것이다.
핵심은 한 테스트를 단독으로 돌리든, 1000개 중 하나로 돌리든, 순서를 섞어 돌리든 결과가 똑같아야 한다.&lt;/p&gt;</description></item></channel></rss>