Mockito에 @Mock 과 @InjectMocks

DongGyun Cho·2023년 3월 1일

Java/Spring

목록 보기
2/3

출처:
https://www.geeksforgeeks.org/difference-between-mock-and-injectmocks-in-mockito/

Mockito를 처음 접한 건 Spring 공부를 하면서였다.

Mockito는 오픈소스 테스팅 프레임워크로 자바 어플리케이션에서 사용되며, 일반적으로 Solitary 단위 테스트를 진행할 때 사용된다.

어떤 기능 A의 동작여부를 테스트 할때 추가적으로 필요로 할 수 있는 B, C 객체들을 Mockito가 가짜 객체로 생성해 주어 A 기능 동작 테스트를 좀더 원활하게 도와준다고 알고있다.

일반적으로 Mockito 를 사용하기 위해서는 테스트 코드 @ExtendWith(MockitoExtension.class) 를 입력하고 사용해 왔다 (다른 방식이 있는지는 모르겠다)

그리고 이 다음에서 가장 헷갈린 내용이 나왔다. @InjectMocks와 @Mock 이다.

참조한 사이트에 내용을 그대로 가져다 쓰면

가장 큰 차이점은

@Mock creates a mock, and @InjectMocks creates an instance of the class and injects the mocks that are created with the @Mock annotations into this instance.

이라고 한다.

예제를 가지고 다시 한번 설명 해보자

두 개의 클래스 StudentPen 이 있고 이는 아래와 같다

class Student {

	private Pen pen;

	public Student(Pen pen) {
		this.pen = pen;
	}

	public String write() {
		return "Student Write with: " + pen.getRedPen();
	}

}
class Pen {

	private String redPen;

	public Pen(String redPen) {
		this.redPen = redPen;
	}

	String getRedPen() {
		return redPen;
	}
}

위 소스 코드를 보면, StudentWrite을 하기 위해서는 Pen 이 필요한걸 알 수 있다. 여기서 Student 클래스 Unit Test를 작성하면

@RunWith(MockitoJUnitRunner.class) // 
class StudentTest {

	@Mock
	Pen pen;

	@InjectMocks
	Student student;

	@Test
	public void writeWithPenTest() throws Exception {
		Mockito.when(pen.getRedPen()).thenReturn("Red Pen");
		assertEquals("Student Write with: Red Pen", student.write());
	}

}

Unit Test 소스를 보면, Mockito가 Pen 클래스를 가짜로 만들어주고 WhenthenReturn 메소드로 행동을 조종한다.

그리고 @InjectMocks 어노테이션으로 Mockito가 PenStudent 클래스에 inject 까지 해준다. 그리고 또 하나, Student 객체를 따로 만들지 않아도 된다. Mockito가 inject 해주기 때문이다.

@Mock@InjectMocks
@Mock은 말그대로 가짜 객체를 생성@InjectMocks는 객체의 인스턴스를 만들고, @Mock 으로 만들어진 객체를 Inject까지 해준다.
@Mock은 테스트 하기위해 클래스가 필요한 객체를 만들기 위해 사용@InjectMocks 는 실제로 테스트 하려는 인스턴스를 생성하기 위해 사용
테스트할때 필요한 종속성들에 @Mock을 붙인다@InjectMocks는 지정된 클래스에 대해 실제 메서드 본문을 실행해야 할 때 사용
when-thenReturn을 꼭 명시해줘야하며 실제 테스트 중에 어떤 클래스의 메소드가 호출되야 할지도 정의해줘야 합니다.실제 테스트하는 메소드가 올바르게 동작하기 위해 mock objects로 초기화된 모든 내부 종속성이 필요한 경우 @InjectMocks 를 사용

간단하게 말해서, 실제 테스트하려는 기능이 service 단이면, service 객체에는 @InjectMock를, 실제 service 클래스 내부에서 사용되는 repository 들은 @Mock 를 붙여준다면, 유닛테스트시 Mockito가 알아서 repository를 생성해서 service 테스트에서 사용 가능하게 해준다.

profile
끈기를 가지고 해보자.

0개의 댓글