Mockito를 사용하여 클래스의 일부 메소드를 조롱하는 방법이 있습니까?
예를 들어, (시피 고안)에서 Stock
클래스 I는 모의 할 getPrice()
및 getQuantity()
(아래 시험 조각에 도시 된 바와 같이) 반환 값이지만 I는 원하는 getValue()
부호화로 곱셈을 수행하는 Stock
클래스
public class Stock {
private final double price;
private final int quantity;
Stock(double price, int quantity) {
this.price = price;
this.quantity = quantity;
}
public double getPrice() {
return price;
}
public int getQuantity() {
return quantity;
}
public double getValue() {
return getPrice() * getQuantity();
}
@Test
public void getValueTest() {
Stock stock = mock(Stock.class);
when(stock.getPrice()).thenReturn(100.00);
when(stock.getQuantity()).thenReturn(200);
double value = stock.getValue();
// Unfortunately the following assert fails, because the mock Stock getValue() method does not perform the Stock.getValue() calculation code.
assertEquals("Stock value not correct", 100.00*200, value, .00001);
}
답변
질문에 직접 대답하기 위해 다른 방법을 조롱하지 않고 몇 가지 방법을 조롱 할 수 있습니다. 이것을 부분 모의 라고합니다 . 자세한 내용 은 부분 모의에 대한 Mockito 설명서 를 참조하십시오.
예를 들어 테스트에서 다음과 같은 작업을 수행 할 수 있습니다.
Stock stock = mock(Stock.class);
when(stock.getPrice()).thenReturn(100.00); // Mock implementation
when(stock.getQuantity()).thenReturn(200); // Mock implementation
when(stock.getValue()).thenCallRealMethod(); // Real implementation
이 경우 절 thenCallRealMethod()
에서 지정하지 않으면 각 메소드 구현이 조롱 when(..)
됩니다.
mock 대신 spy를 사용 하는 다른 방법도 있습니다 .
Stock stock = spy(Stock.class);
when(stock.getPrice()).thenReturn(100.00); // Mock implementation
when(stock.getQuantity()).thenReturn(200); // Mock implementation
// All other method call will use the real implementations
이 경우으로 조롱 된 동작을 정의한 경우를 제외하고 모든 메소드 구현이 실제 구현입니다 when(..)
.
when(Object)
이전 예제에서와 같이 spy와 함께 사용할 때 중요한 함정이 있습니다 . 실제 메소드가 호출됩니다 ( 런타임 stock.getPrice()
전에 평가되기 때문에 when(..)
). 메소드에 호출해서는 안되는 논리가 포함되어 있으면 문제가 될 수 있습니다. 다음과 같이 이전 예제를 작성할 수 있습니다.
Stock stock = spy(Stock.class);
doReturn(100.00).when(stock).getPrice(); // Mock implementation
doReturn(200).when(stock).getQuantity(); // Mock implementation
// All other method call will use the real implementations
다음 org.mockito.Mockito.CALLS_REAL_METHODS
과 같은 다른 가능성이 있습니다 .
Stock MOCK_STOCK = Mockito.mock( Stock.class, CALLS_REAL_METHODS );
이것은 스텁되지 않은 호출을 실제 구현에 위임합니다.
의 구현 때문에, 귀하의 예제와 함께, 나는 그것이 실패 할 것으로 예상 getValue()
의존 quantity
하고 price
, 대신 getQuantity()
과 getPrice()
당신이 조롱 한 일이다.
또 다른 가능성은 모의를 피하는 것입니다.
@Test
public void getValueTest() {
Stock stock = new Stock(100.00, 200);
double value = stock.getValue();
assertEquals("Stock value not correct", 100.00*200, value, .00001);
}