2026년 상식닷컴 선정 식당 & 카페 리스트
최근에 오픈한 호텔을 찾는다면 살펴보세요

JUnit에서 의존성 주입을 사용하는 방법은?

_____
Q1: JUnit에서 의존성 주입(Dependency Injection)이 무엇인가요?
A1: 의존성 주입이란 객체의 생성과 관리 책임을 외부로 분리하여, 필요한 의존 객체를 테스트 대상에 주입하는 기법입니다. JUnit에서는 테스트 코드 내에서 필요한 객체들을 직접 생성하지 않고, 프레임워크나 외부 설정을 통해 주입받아 효율적인 테스트 코드 작성과 유지보수가 가능해집니다.

---

Q2: JUnit 4에서 의존성 주입을 하는 기본적인 방법은?
A2: JUnit 4 자체는 의존성 주입 기능을 내장하고 있지 않으므로, 스프링(Spring) 같은 DI 컨테이너와 결합하여 사용합니다.
- `@RunWith(SpringJUnit4ClassRunner.class)` 어노테이션을 사용해 스프링 컨텍스트와 함께 테스트 실행
- `@ContextConfiguration`으로 스프링 설정 파일 또는 설정 클래스를 지정
- `@Autowired`로 필요한 의존성을 필드에 주입
예:
```java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class MyServiceTest {

@Autowired
private MyService myService;

@Test
public void testService() {
// myService가 스프링에 의해 주입됨
}
}
```

---

Q3: JUnit 5에서 의존성 주입은 어떻게 하나요?
A3: JUnit 5는 확장 모델(Extension model)을 제공하여 DI 프레임워크와 통합할 수 있습니다. 스프링 부트 테스트의 경우 `@ExtendWith(SpringExtension.class)`를 통해 DI가 가능하며, 스프링 부트에서는 `@SpringBootTest` 어노테이션을 주로 사용합니다.
예:
```java
@ExtendWith(SpringExtension.class)
@SpringBootTest
public class MyServiceTest {

@Autowired
private MyService myService;

@Test
void testService() {
// 의존성 주입된 myService 사용
}
}
```

---

Q4: JUnit 자체만으로 의존성 주입을 구현할 수 있나요?
A4: JUnit은 기본적으로 의존성 주입 기능을 제공하지 않습니다. DI를 위해서는 스프링, Guice, Dagger 같은 외부 DI 프레임워크와 연동하거나, 직접 팩토리 메서드 패턴 등을 적용해야 합니다.

---

Q5: 다른 DI 프레임워크와 JUnit의 통합 방법은?
A5:
- Guice : JUnit 4에서는 `GuiceJUnitRunner`나 직접 테스트 클래스 내에서 Injector 생성 후 수동 주입 가능
- Dagger : 앱 컴포넌트에서 만든 객체를 테스트 클래스에 수동 주입하거나, 커스텀 서포트 클래스 사용
- Mockito : `@InjectMocks`와 `@Mock`을 활용해 테스트 대상 객체에 목(mock) 객체 자동 주입 가능

---

Q6: 의존성 주입을 활용할 때 권장하는 테스트 작성 방식은?
A6:
- 테스트 대상 객체는 가급적 생성자 주입 방식을 사용해 테스트 용이성 향상
- 가능하면 목(Mock) 객체를 사용해 독립적인 단위 테스트 작성
- 복잡한 의존성은 DI 컨테이너에서 관리하고, 테스트용 설정은 별도 프로파일이나 설정으로 분리

---

Q7: 필드 주입과 생성자 주입 중 어떤 방식을 쓸까요?
A7: 생성자 주입을 권장합니다. 생성자 주입은 불변성을 보장하고, 테스트 작성 시 명시적으로 의존성을 주입하기 좋기 때문입니다. 필드 주입은 테스트에서 Mock 객체 주입이 어렵고, 코드 가독성이 떨어질 수 있습니다.

---

Q8: JUnit 5에서 직접적인 의존성 주입 없이도 테스트에 의존성을 주입하는 방법은?
A8: `@TestInstance(Lifecycle.PER_CLASS)`를 사용하면 필드에 초기화 로직을 넣거나, `@BeforeEach` 메서드를 활용해 필요한 객체를 생성·초기화할 수 있습니다. 그러나 이는 DI 프레임워크만큼 편리하지 않습니다.

---

Q9: 의존성 주입으로 인해 테스트 성능에 영향을 주나요?
A9: 스프링 등 DI 컨테이너는 테스트 실행 시 컨텍스트를 로드하므로 초기화 비용이 있습니다. 이를 줄이려면 `@DirtiesContext` 사용을 자제하고, 가능한 테스트 클래스별로 컨텍스트를 재사용하는 게 좋습니다.

---

요약:
JUnit 자체는 DI 기능이 없으므로, 스프링의 `@Autowired`와 `@ExtendWith(SpringExtension.class)` 또는 `@RunWith(SpringJUnit4ClassRunner.class)` 등을 활용해 DI하는 것이 일반적입니다. 생성자 주입과 외부 DI 프레임워크 활용이 권장되며, 목(Mock) 프레임워크와 함께 사용하면 효과적입니다.
JUnit에서 의존성 주입(Dependency Injection, DI)을 사용하는 방법은 테스트 코드에서 객체 간의 의존성을 명확히 하고, 보다 유연하고 유지보수하기 쉬운 테스트를 작성하는 데 도움을 줍니다.

JUnit 자체는 DI 기능을 제공하지 않지만, Spring Framework와 같은 DI 지원 프레임워크와 함께 사용하거나, JUnit 5의 확장 기능을 활용하여 DI를 구현할 수 있습니다.

각각의 주요 방법을 자세히 설명하면 다음과 같습니다.

1. Spring Framework와 함께 JUnit에서 DI 사용하기 대부분의 경우, 실제 애플리케이션에서 DI를 적용한 컴포넌트를 테스트할 때 Spring의 DI 컨테이너를 활용합니다.

Spring은 테스트용으로 JUnit과 잘 통합되며, 테스트 클래스 내에 구성한 빈(Bean)을 자동 주입할 수 있습니다.

1-1. @ExtendWith(SpringExtension.class)과 @ContextConfiguration 사용 (JUnit 5 기준) - JUnit 5부터는 `@ExtendWith(SpringExtension.class)` 어노테이션을 테스트 클래스에 사용해 Spring 컨텍스트와 연동합니다.

- `@ContextConfiguration` 또는 `@SpringBootTest`를 이용해 테스트에 필요한 Spring 설정 파일이나 클래스, Spring Boot 환경을 지정합니다.

- `@Autowired`를 통해 테스트 대상 컴포넌트나 의존 객체를 주입합니다.

```java import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.junit.jupiter.api.extension.ExtendWith; @ExtendWith(SpringExtension.class) @ContextConfiguration(classes = {AppConfig.class}) public class MyServiceTest { @Autowired private MyService myService; @Test public void testService() { // myService가 DI된 상태로 테스트 가능 assertNotNull(myService); myService.performAction(); } } ``` - `AppConfig.class`는 애플리케이션의 Spring 설정 클래스이며, 빈 정의를 포함합니다.

- Spring Boot 프로젝트라면 `@SpringBootTest`를 써서 쉽게 컨텍스트를 띄울 수 있습니다.

1-2. @MockBean 등과 혼용하기 - Spring Boot Test에서는 `@MockBean`을 써서 특정 의존성을 mock 객체로 주입할 수 있습니다.

- 이를 이용하면 더 세밀하게 의존성을 관리할 수 있습니다.

---

2. JUnit 5 자체 확장 기능을 통해 DI 흉내 내기 JUnit 5는 테스트 생명주기에 개입할 수 있는 확장(extension) 메커니즘을 제공합니다.

이를 이용해 간단한 DI 구현도 가능합니다.

예를 들어 생성자 주입이나 필드 주입을 확장 기능으로 모방할 수 있습니다.

- `ParameterResolver` 인터페이스를 구현해 테스트 메소드, 생성자 등에 매개변수를 주입하는 식입니다.

```java import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolver; public class MyServiceParameterResolver implements ParameterResolver { @Override public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { return parameterContext.getParameter().getType() == MyService.class; } @Override public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) { return new MyService(); // 간단한 직접 생성 또는 복잡한 DI 로직 가능 } } ``` 테스트 클래스에서: ```java @ExtendWith(MyServiceParameterResolver.class) public class MyServiceTest { @Test public void testService(MyService myService) { // 생성자나 메소드 파라미터로 주입받음 assertNotNull(myService); myService.performAction(); } } ``` 이 방법은 Spring 없이도 원하는 객체를 테스트 메소드에 주입할 수 있지만, 복잡한 DI 컨테이너 기능을 대체하기엔 한계가 있습니다.

---

3. 수동 DI (Constructor/Setter Injection) 활용 JUnit 자체가 DI를 지원하지 않으므로, 가장 간단한 방법은 테스트 클래스에 명시적으로 의존 객체를 주입하거나, 생성자 및 필드에 직접 할당하는 방법입니다.

```java public class MyServiceTest { private MyDependency dependency = new MyDependency(); private MyService myService = new MyService(dependency); @Test public void testService() { myService.performAction(); // 검증 코드 } } ``` 이 방식은 명확하고 간단하지만, 매번 의존성 객체를 직접 생성해줘야 하므로 테스트 코드가 복잡해질 수 있습니다.

--- 요약 - Spring Framework와 통합: 실제 개발 환경에서 가장 많이 사용하며, `@ExtendWith(SpringExtension.class)` + `@ContextConfiguration` 또는 `@SpringBootTest` + `@Autowired` 조합으로 DI를 가장 쉽게 구현. - JUnit 5 확장기능: ParameterResolver 등을 사용해 테스트 메소드에 의존성을 주입하는 고급 기법. Spring이 없는 가벼운 프로젝트에 적합. - 직접 주입: 테스트 코드에서 직접 생성자나 필드 할당으로 의존성 주입을 흉내. 따라서 JUnit에서 DI를 사용하려면 보통 Spring TestContext 프레임워크를 활용하거나, 필요에 따라 JUnit 5의 확장 기능을 직접 구현하는 방식을 사용합니다.

이때 의존성 주입 어노테이션이나 메커니즘을 적용함으로써 테스트 코드의 재사용성과 유연성을 크게 높일 수 있습니다.

작성자: 정서율 [비회원] | 작성일자: 1년 전 2025-05-26 02:51:05
조회수: 180 | 댓글: 0 | 좋아요: 0 | 싫어요: 0
내용이 부정확하다면 싫어요를 클릭해주세요.