동일한 인수를 가진 동일한 메서드에 대한 여러 콜에서 Mockito 사용
이후 호출 시 stubbed 메서드가 다른 개체를 반환하도록 하는 방법이 있습니까?이 작업을 통해 특정되지 않은 응답을 테스트하고 싶습니다.ExecutorCompletionService
즉, 방법의 반환 순서에 관계없이 결과가 일정하게 유지되도록 테스트한다.
테스트하려는 코드는 다음과 같습니다.
// Create an completion service so we can group these tasks together
ExecutorCompletionService<T> completionService =
new ExecutorCompletionService<T>(service);
// Add all these tasks to the completion service
for (Callable<T> t : ts)
completionService.submit(request);
// As an when each call finished, add it to the response set.
for (int i = 0; i < calls.size(); i ++) {
try {
T t = completionService.take().get();
// do some stuff that I want to test
} catch (...) { }
}
어때.
when( method-call ).thenReturn( value1, value2, value3 );
thenReturn의 괄호 안에 원하는 수만큼 인수를 넣을 수 있습니다.단, 모두 올바른 유형입니다.첫 번째 값은 메서드가 처음 호출될 때 반환되고 두 번째 응답이 반환됩니다.마지막 값은 다른 값이 모두 사용되면 반복적으로 반환됩니다.
이것은, 다음의 방법으로 실행할 수 있습니다( 와의 체인을 접속하는 경우).
when(someMock.someMethod()).thenAnswer(new Answer() {
private int count = 0;
public Object answer(InvocationOnMock invocation) {
if (count++ == 1)
return 1;
return 2;
}
});
또는 동등한 정적 방법을 사용합니다.
doAnswer(new Answer() {
private int count = 0;
public Object answer(InvocationOnMock invocation) {
if (count++ == 1)
return 1;
return 2;
}
}).when(someMock).someMethod();
앞서 설명한 바와 같이 거의 모든 콜은 체인이 가능합니다.
전화할 수 있게
when(mock.method()).thenReturn(foo).thenReturn(bar).thenThrow(new Exception("test"));
//OR if you're mocking a void method and/or using spy instead of mock
doReturn(foo).doReturn(bar).doThrow(new Exception("Test").when(mock).method();
자세한 내용은 모키토의 설명서를 참조하십시오.
대부분의 콜은 체인이 가능합니다.
doReturn(null).doReturn(anotherInstance).when(mock).method();
BDD 스타일:
import static org.mockito.BDDMockito.given;
...
given(yourMock.yourMethod()).willReturn(1, 2, 3);
클래식 스타일:
import static org.mockito.Mockito.when;
...
when(yourMock.yourMethod()).thenReturn(1, 2, 3);
명시적 스타일:
...
when(yourMock.yourMethod())
.thenReturn(1)
.thenReturn(2)
.thenReturn(3);
arg에 따라 다름
2개의 arg가 있다고 가정하고 두 번째 (목록)arg의 크기를 확인합니다.
...
when(yourMock.yourMethod(any(), anyList()))
.thenAnswer(args -> ((List) args.getArgument(1)).size() < 2
? 1
: 3);
arg는 오브젝트이기 때문에 타입에 arg를 붙여야 합니다.^^^를 캐스팅합니다.(List)
저 같은 경우에는요.
BDD
...
given(yourMock.yourMethod(any(), anyList()))
.willAnswer(args -> ((List) args.getArgument(1)).size() < 2
? 1
: 3);
구현했습니다.MultipleAnswer
모든 콜에서 다른 응답을 스터핑하는 데 도움이 되는 클래스입니다.다음은 코드입니다.
private final class MultipleAnswer<T> implements Answer<T> {
private final ArrayList<Answer<T>> mAnswers;
MultipleAnswer(Answer<T>... answer) {
mAnswers = new ArrayList<>();
mAnswers.addAll(Arrays.asList(answer));
}
@Override
public T answer(InvocationOnMock invocation) throws Throwable {
return mAnswers.remove(0).answer(invocation);
}
}
doReturn ( value 1, value 2, value 3 )의 경우( method-call )
@[ Igor Nikolaev ]의 8년 전 답변과 관련하여Answer
Java 8에서 사용할 수 있는 람다 식을 사용하여 어느 정도 단순화할 수 있습니다.
when(someMock.someMethod()).thenAnswer(invocation -> {
doStuff();
return;
});
또는 더 간단하게:
when(someMock.someMethod()).thenAnswer(invocation -> doStuff());
다음은 다른 메서드콜에서 다른 인수를 반환하는 일반적인 메서드로 사용할 수 있습니다.필요한 것은 각 콜에서 오브젝트를 취득하는 순서로 어레이를 전달하기만 하면 됩니다.
@SafeVarargs
public static <Mock> Answer<Mock> getAnswerForSubsequentCalls(final Mock... mockArr) {
return new Answer<Mock>() {
private int count=0, size=mockArr.length;
public Mock answer(InvocationOnMock invocation) throws throwable {
Mock mock = null;
for(; count<size && mock==null; count++){
mock = mockArr[count];
}
return mock;
}
}
}
예.getAnswerForSubsequentCalls(mock1, mock3, mock2);
첫 번째 콜에서는 mock1 오브젝트를, 두 번째 콜에서는 mock3 오브젝트를, 세 번째 콜에서는 mock2 오브젝트를 반환합니다.다음과 같이 사용해야 합니다.when(something()).doAnswer(getAnswerForSubsequentCalls(mock1, mock3, mock2));
이것은 와 거의 비슷하다.when(something()).thenReturn(mock1, mock3, mock2);
이것은 질문과는 직접적인 관계가 없습니다.하지만 같은 사슬에 묶고 싶었죠.
여러 인수를 사용하여 동일한 메서드콜을 확인하려고 할 경우 Mockito에서 다음 시간 기능을 사용할 수 있습니다.검증하지 않으면 필요 없습니다.
모키토.verify(method, times(n)).methoscall();
여기서 'n'은 모의가 호출된 횟수입니다.
이것은 기본적이거나 명백한 경우가 있습니다만, 저처럼 테스트하는 메서드에 대해 콜당 미지의 횟수라고 불리는 메서드에 대해 여러 콜을 모의하려고 하는 경우, 예를 들어 다음과 같습니다.
public String method(String testArg) {
//...
while(condition) {
someValue = someBean.nestedMethod(); // This is called unknown number of times
//...
}
//...
}
다음과 같은 작업을 수행할 수 있습니다.
@Test
public void testMethod() {
mockNestedMethodForValue("value1");
assertEquals(method("arg"), "expected1");
mockNestedMethodForValue("value2");
assertEquals(method("arg"), "expected2");
mockNestedMethodForValue("value3");
assertEquals(method("arg"), "expected3");
}
private void mockNestedMethodForValue(String value) {
doReturn(value).when(someBeanMock).nestedMethod();
}
여기 꽤 간단하고 명확한 BDD 스타일의 작업 예가 있습니다.
given(carRepository.findByName(any(String.class))).willReturn(Optional.empty()).willReturn(Optional.of(MockData.createCarEntity()));
'어울리다'를 사용할 수 요.LinkedList
및 .예:
MyService mock = mock(MyService.class);
LinkedList<String> results = new LinkedList<>(List.of("A", "B", "C"));
when(mock.doSomething(any())).thenAnswer(invocation -> results.removeFirst());
값의 동적 목록이 있는 경우 다음을 사용할 수 있습니다.
import org.mockito.AdditionalAnswers;
when(mock.method()).thenAnswer(AdditionalAnswers.returnsElementsOf(myListOfValues));
언급URL : https://stackoverflow.com/questions/8088179/using-mockito-with-multiple-calls-to-the-same-method-with-the-same-arguments
'programing' 카테고리의 다른 글
Java 열거 멤버 비교: == 또는 equals()? (0) | 2022.08.13 |
---|---|
Vuejs의 매초 악리콜이 느리다 (0) | 2022.08.13 |
Java에서 밀리초를 "X분, x초"로 변환하는 방법 (0) | 2022.08.13 |
자바 파괴자가 있나요? (0) | 2022.08.13 |
Java에서 트리 데이터 구조를 구현하려면 어떻게 해야 합니까? (0) | 2022.08.13 |