원문: https://testing.googleblog.com/2008/06/tott-friends-you-can-depend-on.html (Translated by Google Gemini)


테스트 환경에서 사용하기 너무 어렵거나 느린 것에 의존하는 코드를 테스트하고 싶을 때는, 의존성 대신 테스트 더블을 사용하세요. 더미(Dummy)는 API를 만족시키기 위해 가짜 입력 값을 전달합니다.

Item item = new Item(ITEM_NAME);
ShoppingCart cart = new ShoppingCart();
cart.add(item, QUANTITY);
assertEquals(QUANTITY, cart.getItem(ITEM_NAME));

스텁(Stub) 은 실제 객체를 오버라이드하고 하드코딩된 값을 반환합니다. 스텁만을 사용한 테스트는 상태 기반 테스트입니다. 시스템을 실행한 다음 시스템이 예상된 상태인지 확인합니다.

ItemPricer pricer = new ItemPricer() {
  public BigDecimal getPrice(String name){ return PRICE; }
};
ShoppingCart cart = new ShoppingCart(pricer);
cart.add(dummyItem, QUANTITY);
assertEquals(QUANTITY*PRICE, cart.getCost(ITEM_NAME));

목(Mock) 은 값을 반환할 수 있지만, 메서드가 호출되는 방식에도 신경을 씁니다. (“엄격한 목(strict mocks)” 은 메서드 호출 순서에 신경을 쓰는 반면, “유연한 목(lenient mocks)” 은 그렇지 않습니다.) 목을 사용한 테스트는 상호작용 기반 테스트입니다. 목에 기대값을 설정하고, 목은 실행될 때 기대값을 검증합니다. 이 예시는 JMock을 사용하여 목을 생성합니다(EasyMock, Mockito 도 유사합니다):

Mockery context = new Mockery();
final ItemPricer pricer = context.mock(ItemPricer.class);
context.checking(new Expectations() {{
  one(pricer).getPrice(ITEM_NAME);
  will(returnValue(PRICE));
}});
ShoppingCart cart = new ShoppingCart(pricer);
cart.add(dummyItem, QUANTITY);
cart.getCost(ITEM_NAME);
context.assertIsSatisfied();

스파이(Spy) 는 목과 동일한 목적을 수행합니다. 값을 반환하고 메서드 호출을 기록합니다. 그러나 스파이를 사용한 테스트는 상호작용 기반이 아닌 상태 기반이므로, 테스트는 스텁 스타일 테스트와 더 유사하게 보입니다.

TransactionLog log = new TransactionLogSpy();
ShoppingCart cart = new ShoppingCart(log);
cart.add(dummyItem, QUANTITY);
assertEquals(1, logSpy.getNumberOfTransactionsLogged());
assertEquals(QUANTITY*PRICE, log.getTransactionSubTotal(1));

페이크(Fake) 는 실제 구현을 더 간단한 페이크 구현으로 대체합니다. 고전적인 예시는 인메모리 데이터베이스를 구현하는 것입니다.

Repository repo = new InMemoryRepository();
ShoppingCart cart = new ShoppingCart(repo);
cart.add(dummyItem, QUANTITY);
assertEquals(1, repo.getTransactions(cart).Count);
assertEquals(QUANTITY, repo.getById(cart.id()).getQuantity(ITEM_NAME));

이 에피소드에서는 예시로 Java를 사용했지만, 위에 언급된 모든 “친구들"은 C++, Python, JavaScript 및 아마도 여러분이 가장 좋아하는 언어에도 확실히 존재합니다.