Spock Framework Reference Documentation 을 보면 다른 종류의 Mock Objects로 Stub을 소개하고 있다.
레퍼런스에서는 mock 은 stubbing과 mocking을 둘 다 할 수 있고 ,stub은 단지 stubbing 만 할 수 있다고 나와 있다.
가장 큰 차이는 stub은 몇 번 호출되었는지를 물어볼 수 없는 차이가 있다.
하지만 이것으로는 Mock() 와 Stub()을 언제 써야할 지 명확하지 않다.
우연히 처음에는 Stub()을 사용하다가 카운팅 여부를 확인해야 해서 이후에 Mock()으로 바꾸는 작업이 있었는데
이 side-effect로 다른 테스트 케이스가 깨지는 경험을 하게 되어 차이를 이제야 이해할 수 있었다.
예를 들어 아래와 같이 CancelService가 OrderService와 InventoryService를 내부에서 사용하고 있다.
이것을 테스트 코드로 skeleton을 구성할 때 아래와 같이 구성이 가능하다.
import spock.lang.Specification
import spock.lang.Subject
class CancelServiceSpec extends Specification {
@Subject
private CancelService sut
private OrderService orderService
private InventoryService inventoryService
def setup() {
orderService = Stub()
inventoryService = Stub()
sut = new CancelService(orderService, inventoryService)
}
만약 테스트 관심사가 OrderService 일 경우 InventoryService 의 경우 Stub()으로 되어 있기 때문에
CancelService 내부에서 InventoryService의 메서드가 호출이 되어도 적절한 객체가 반환이 된다.
만약 아래와 같이 Mock() 으로 바뀌게 되면 stubbing을 해주지 않았을 경우 null 이 반환된다.
import spock.lang.Specification
import spock.lang.Subject
class CancelServiceSpec extends Specification {
@Subject
private CancelService sut
private OrderService orderService
private InventoryService inventoryService
def setup() {
orderService = Stub()
inventoryService = Mock() // mock!
sut = new CancelService(orderService, inventoryService)
}
따라서 경우에 따라서 NupNullPointerException 가 발생하면서 Stub()일 때는 문제 없던 다른 테스트 코드에서 예외가 발생하면서 테스트가 깨질 수 있다.
'Programing > OpenSource' 카테고리의 다른 글
[tomcat] ARP 경고 해결하기 (0) | 2020.11.13 |
---|---|
[Spring] org.springframework.dao 예외 클래스 (0) | 2020.10.27 |
[slf4j] MDC에 put만 계속한다면 (0) | 2020.06.15 |
[JPA] Hibernate + MariaDB : count(*)의 매핑이 BigInteger로 되는 이유는? (0) | 2020.06.12 |
[Hibernate] JPA 스키마 검증은 어떻게 수행될까? (0) | 2020.06.01 |