일부 메서드는 조롱하지 않고 Mockito를 사용합니다.
모키토를 사용해서 수업 중에 몇 가지 방법을 비웃는 방법은 없을까?
예를 들어, (인정된) 이 경우Stock내가 조롱하고 싶은 수업getPrice()그리고.getQuantity()(아래 테스트 스니펫에 나타난 바와 같이) 값을 반환하지만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(..)절을 클릭합니다.
또한 모의 대신 스파이를 사용할 가능성도 있습니다.
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)이전 예시와 같이 스파이를 사용합니다.진짜 메서드가 호출됩니다(이유는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);
}
모키토에서는 Spy를 통해 수업의 부분적인 조롱도 지원됩니다.
List list = new LinkedList();
List spy = spy(list);
//optionally, you can stub out some methods:
when(spy.size()).thenReturn(100);
//using the spy calls real methods
spy.add("one");
spy.add("two");
//size() method was stubbed - 100 is printed
System.out.println(spy.size());
상세한 것에 대하여는,및 문서를 참조해 주세요.
문서에 따르면:
Foo mock = mock(Foo.class, CALLS_REAL_METHODS);
// this calls the real implementation of Foo.getSomething()
value = mock.getSomething();
when(mock.getSomething()).thenReturn(fakeValue);
// now fakeValue is returned
value = mock.getSomething();
네가 원하는 건org.mockito.Mockito.CALLS_REAL_METHODS문서에 따르면:
/**
* Optional <code>Answer</code> to be used with {@link Mockito#mock(Class, Answer)}
* <p>
* {@link Answer} can be used to define the return values of unstubbed invocations.
* <p>
* This implementation can be helpful when working with legacy code.
* When this implementation is used, unstubbed methods will delegate to the real implementation.
* This is a way to create a partial mock object that calls real methods by default.
* <p>
* As usual you are going to read <b>the partial mock warning</b>:
* Object oriented programming is more less tackling complexity by dividing the complexity into separate, specific, SRPy objects.
* How does partial mock fit into this paradigm? Well, it just doesn't...
* Partial mock usually means that the complexity has been moved to a different method on the same object.
* In most cases, this is not the way you want to design your application.
* <p>
* However, there are rare cases when partial mocks come handy:
* dealing with code you cannot change easily (3rd party interfaces, interim refactoring of legacy code etc.)
* However, I wouldn't use partial mocks for new, test-driven & well-designed code.
* <p>
* Example:
* <pre class="code"><code class="java">
* Foo mock = mock(Foo.class, CALLS_REAL_METHODS);
*
* // this calls the real implementation of Foo.getSomething()
* value = mock.getSomething();
*
* when(mock.getSomething()).thenReturn(fakeValue);
*
* // now fakeValue is returned
* value = mock.getSomething();
* </code></pre>
*/
따라서 코드는 다음과 같습니다.
import org.junit.Test;
import static org.mockito.Mockito.*;
import static org.junit.Assert.*;
public class StockTest {
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, withSettings().defaultAnswer(CALLS_REAL_METHODS));
when(stock.getPrice()).thenReturn(100.00);
when(stock.getQuantity()).thenReturn(200);
double value = stock.getValue();
assertEquals("Stock value not correct", 100.00 * 200, value, .00001);
}
}
문의처Stock stock = mock(Stock.class);콜org.mockito.Mockito.mock(Class<T>)다음과 같이 표시됩니다.
public static <T> T mock(Class<T> classToMock) {
return mock(classToMock, withSettings().defaultAnswer(RETURNS_DEFAULTS));
}
값의 문서RETURNS_DEFAULTS설명:
/**
* The default <code>Answer</code> of every mock <b>if</b> the mock was not stubbed.
* Typically it just returns some empty value.
* <p>
* {@link Answer} can be used to define the return values of unstubbed invocations.
* <p>
* This implementation first tries the global configuration.
* If there is no global configuration then it uses {@link ReturnsEmptyValues} (returns zeros, empty collections, nulls, etc.)
*/
위의 답변에서 이미 언급한 바와 같이, Mockito의 스파이 방법을 사용하는 부분적인 조롱이 당신의 문제를 해결하는 방법이 될 수 있습니다.구체적인 사용 사례에 대해서는 DB 룩업을 조롱하는 것이 더 적절할 수 있다는 데 어느 정도 동의합니다.제 경험상, 이것이 항상 가능한 것은 아닙니다.적어도 다른 회피책 없이는 말이죠.그것은 매우 번거롭거나 적어도 깨지기 쉽다고 생각됩니다.이런 부분적인 조롱은 동맹의 모키토 버전에서는 통하지 않습니다.최소 1.8.0을 사용해야 합니다.
이 답변을 게시하는 대신 원래 질문에 간단한 코멘트를 작성했을 뿐이지만 StackOverflow에서는 허용되지 않습니다.
한 가지만 더요여기서 여러 번 질문을 하면 문제를 이해하려고 노력하지 않고 "왜 이렇게 하고 싶은가"라는 코멘트를 받는다는 것은 정말 이해할 수 없습니다.특히 부분적인 조롱의 필요성에 관해서는 실제로 도움이 될 만한 사용 사례가 많이 있습니다.그래서 모키토에서 온 사람들이 그 기능을 제공했어요.물론 이 기능을 과도하게 사용해서는 안 됩니다.그러나 매우 복잡한 방법으로 확립할 수 없었던 테스트 케이스 설정에 대해 이야기할 때는 스파이 기능을 사용해야 합니다.
언급URL : https://stackoverflow.com/questions/14970516/use-mockito-to-mock-some-methods-but-not-others
'programing' 카테고리의 다른 글
| 태그 부착 구조 초기화 구문이란 무엇입니까? (0) | 2022.07.24 |
|---|---|
| Java 8: 스트림과 컬렉션의 퍼포먼스 (0) | 2022.07.24 |
| Maven surefire가 ForkedBooter 클래스를 찾을 수 없음 (0) | 2022.07.24 |
| 프로덕션 빌드 전용 오류:Vuetify 대상 데이터 앱을 찾을 수 없습니다. (0) | 2022.07.24 |
| 이 GCC 오류 "..."에 맞게 재배치가 잘렸습니다." " " " " ? ? (0) | 2022.07.24 |