저번 퍼사드 패턴 적용기 에서
언급했던 테스트에 대해서 써보려고 한다.
바로 정리해보도록 하겠다.
이전의 Mockito 에 대해서 정리한 글이 있다.
일단 퍼사드 패턴을 적용함으로써
여러개의 서비스를 하나의 퍼사드가 관리해주는 형태로 작성을 했었다.
그러면서 하나의 Service
<- 하나의 Repository
가 되는 구조를 가지게 되었다.
여기서 @Mock
이 등장하게 되었는데,
기존의 @Autowired
방식으로 사용했다면 꿈도 못꾸는 가짜 객체 주입이다.
Service service = new Service();
해서 @Autowired
된 객체를 주입할 수 있을까?
답은 아니라고 생각한다. 의존을 자동으로 주입해주기 때문에 뭘 할당할 수 없는 구조였다.
하지만 생성자 주입을 해준다면??? 얘기는 다르다.
Service service = new Service(repotisory);
가되기 때문에 @Mock
으로 가짜 객체를 서비스에
주입해서 POJO
단위 테스트를 진행할 수 있게 된다.
@Service
@Transactional
public class Service {
private final Repository repository;
public Service(final Repository repository) {
this.repository = repository;
}
public Foo findByName(final String name) {
repository.findByName(name).orElseThrow();
}
}
public interface Repository extends JpaRepository<Foo, Long> {
Optional<Foo> findByName(final String name);
}
@Getter
public class Foo {
private String name;
private int age;
public Foo (final String name, final int age) {
this.name = name;
this.age = age;
}
}
@ExtendWith(MockitoExtension.class) //Mockito 의존성을 가져온다.
public class ServiceTest {
@Mock
private Repository repository;
@InjectMocks //주입받을 클래스
private Service service; //(Service service = new Service(repository);) 와 같은구조가 된다.
@Test
void test() {
//given
Foo foo = new Foo("테스트", 15);
//when
// 여기서 mockito로 가짜객체가 어떤 조건을 실행했을 때 어떤 객체를 돌려주게끔 설정해준다.
BDDMockito.given(repository.findByName(anyString()).willReturn(Optional.ofNullable(foo));
//then
Foo foo = service.findByName("테스트");
verify(service).findByName("테스트"); //service 객체의 findByName메소드에 name값이 '테스트' 인 것을 호출했는지 검증
Assertions.assertThat(foo.getName()).isEqualTo("테스트");
Assertions.assertThat(foo.getAge()).isEqualTo(15);
}
}
이런식으로 POJO 테스트를 진행할 수 있다.
이 구조로 하여금 더더욱 DI가 중요하다는 것을 깨닫고
기초가 중요하다는 것을 다시금 인지하게 되었다.
간략하게 한줄로 설명하자면 @Spy
는 실제 인스턴스를 사용,
@Mock
은 가짜 인스턴스를 사용한다.
그래서 @Spy
는 Mockito.when()
이나 BDDMockito.given()
메서드 등으로 메서드의 행위를 지정해 주지 않으면
@Spy
객체를 만들 때 사용한 실제 인스턴스의 메서드를 호출한다.
그래서 @Spy
는 실제 인스턴스를 필요로 하기 때문에 인스턴스를 할당 해주어야 사용이 가능하다.
이걸로 미루어 보아 두개를 상황에 따라 적절하게 엮어서 사용해줘야 한다는 것을 느낀다. 물론 적용 해볼 경험이 필요하다!!!!