grep

Engineering

Spock 살펴보기

NHN

2021년 2월 22일

원문에서 보기 ↗

Spock이란?

기존 JUnit의 단점

Spock 세팅

1.png 2.png 이렇게 gradle이나 maven에 선언을 해주고 groovy 파일 생성 후 Specification 클래스를 상속받으면 spock을 사용할 수 있습니다.

Spock의 구성

3.png Spock 공식 문서에서는 6개의 라이프 사이클을 소개하고 있습니다. 4.png setup과 cleanup은 각각 JUnit에서의 @before,@after에 해당하는 기능을 하고 있습니다. 5.png when은 테스트할 대상 코드를 실행합니다. then은 테스트할 대상 코드의 결과를 검증하는데 assert 문이 따로 필요 없고 이 블록 범위에선 한 줄 한 줄이 자동 assert가 됩니다. 6.png expect는 when과 then을 합친 것으로 간단한 검증을 하기에 적합합니다. where의 경우는 개인적으로 JUnit에 비해 정말 편리하다고 느끼는 부분인데 expect나 when에서 테스트할 코드의 변수를 |로 구분해서 나열할 수 있습니다. 7.png JUnit으로 같은 테스트를 작성할 경우 위와 같이 중복 코드가 많이 발생하게 됩니다.

Mock

테스트 시 정말 자주 사용하게 되는 mocking 또한 Spock에서 간단하게 처리할 수 있습니다. 8.png given 블록의 첫 줄처럼 간단하게 mocking 할 수 있으며 반환 값은 >>로 지정해 줄 수 있습니다. 9.png 만약 exception을 처리해야 한다면 위와 같이 작성할 수 있습니다.

Bean의 mocking

Spock을 쓴다 하더라도 Spring의 Bean을 mocking하려면 Mockito 방식을 사용해야 합니다. 10.png 하지만 이 경우 groovy 언어의 특성상 Overloading Method를 mocking할 때 어떤 메서드를 mocking 해야 할지 선택하지 못해 mocking 실패로 테스트가 실패하게 됩니다. 11.png 그럴 경우 Spock에서 제공하는 DetachedMockFactory 팩토리를 통한 Mock 생성을 통해 bean에 대한 mock 생성이 가능합니다. 하지만 이 경우에도 문제가 있는데 JpaRepository의 경우 mocking하지 못합니다. 때문에 JpaRepository 인터페이스 mocking이 필요할 경우 JUnit 또는 Spock에서 Mockito를 사용해야 합니다.

Spock 후기

조사를 시작하면서 처음 다가왔던 부분은 Spock이 저에게는 조금 생소한 언어였던 groovy 언어를 사용하는데 사실 크게 다른 부분은 보이지 않아서 언어의 문제보다는 테스트 코드 작성의 편리함이 더 크게 느껴졌습니다. 아무래도 기존에 많이 접해왔던 JUnit과 비교를 할 수밖에 없는데 Spock이 가지는 강점은 검증 문서의 편리함도 있었지만, 가장 좋았던 부분은 where 블록을 통한 코드 중복의 최소화였습니다. 기존에 테스트를 하다 보면 하나의 프로세스에 대해서 여러 가지 경우로 테스트를 하게 되는데 그런 경우 코드 중복을 확실하게 줄일 수 있는 Spock을 사용하면 좋을 것 같습니다. 하지만 bean을 mocking 하게 될 경우 조사하면서 mocking이 제대로 되지 않아 고생한 것도 있고 해결하지 못한 부분도 있기 때문에 그런 부분에서는 확실하게 숙지하기 전까지는 JUnit을 사용하는 것이 좀 더 안정적일 것 같습니다.