모키토:메서드를 감시하는 것은 원래 메서드를 호출하는 것입니다.
Mockito 1.9.0을 사용하고 있습니다.JUnit 테스트에서 수업의 단일 메서드에 대한 행동을 조롱하고 싶기 때문에
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
두 줄에 " " " 입니다.myClassSpy.method1()
가 실제로 호출되고 있습니다.그 결과적으로는 예외가 발생합니다.내가 모크를 사용하는 이유는 나중에, 언제든지myClassSpy.method1()
되지 않고 방법은 되지 않습니다.myResults
오브젝트가 반환됩니다.
MyClass
는 인터페이스이며, 「」입니다.myInstance
게게중 、 거거거,,, 、 ,,현구요요요 。
이 스파이 행위를 바로잡으려면 어떻게 해야 하나요?
공식 문서를 인용하겠습니다.
진짜 사물을 염탐하는 데 중요한 역할을 해!
간첩을 제압하기 위해 (물건을) 사용하는 것이 불가능할 때가 있다.예:
List list = new LinkedList(); List spy = spy(list); // Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty) when(spy.get(0)).thenReturn("foo"); // You have to use doReturn() for stubbing doReturn("foo").when(spy).get(0);
이 경우 다음과 같이 됩니다.
doReturn(resultsIWant).when(myClassSpy).method1();
2.0을 하여 Mockito 2.0을 모두 .any()
의 ''에 대한nullable()
실제 콜을 스터브하기 위해서입니다.
내 경우는 인정된 답변과 달랐다.해당 패키지에 존재하지 않는 인스턴스의 패키지-프라이빗 메서드를 조롱하려고 했습니다.
package common;
public class Animal {
void packageProtected();
}
package instances;
class Dog extends Animal { }
그리고 시험수업
package common;
public abstract class AnimalTest<T extends Animal> {
@Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
@Test
public void myTest(){}
}
컴파일은 올바르지만 테스트를 셋업하려고 하면 실제 메서드가 호출됩니다.
메서드가 보호되고 있다고 선언하거나 공개적으로 선언하면 문제가 해결되므로 문제가 해결되지 않습니다.
Tomasz Nurkiewicz의 답변이 모든 것을 말해주는 것은 아닌 것 같다!
NB Mockito 버전: 1.10.19.
저는 모키토 신참이기 때문에, 이하의 행동을 설명할 수 없습니다.이 답변을 개선할 수 있는 전문가가 있으면, 부담없이 해 주세요.
가 되고 있는 은, 「」입니다.getContentStringValue
는 없습니다. final
그리고 아니다 static
.
이 회선은 원래 메서드를 호출합니다.getContentStringValue
:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
이 라인은 원래 메서드를 호출하지 않습니다.getContentStringValue
:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
할 수 없는 로, ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★.isA()
"method"(?) 이 됩니다.doReturn
패하하다
. 둘 다 기 involved involved both both let involved bothaturesaturesaturesaturesaturesaturesaturesaturesaturesaturesatures both both both both.둘다static
의 Matchers
다 null
아마 그 일 것이다.Class
파라미터가 조사될 때 오브젝트가 전달되었지만 결과는 계산되지 않았거나 폐기되지 않았습니다.null
할 수 , 좋겠다고 이 메서드의 는 사용할 수 것입니까?isA( ... )
★★★★★★★★★★★★★★★★★」any( ... )
돌려주다null
파라미터가 * " " " " " 입니다.*<T>
어쨌든:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
API 문서에서는 이에 대한 단서를 제공하지 않습니다.또, 이러한 「콜하지 않는 방법」의 동작의 필요성은 「매우 드물다」라고 말하고 있는 것 같습니다.개인적으로 저는 항상 이 기술을 사용합니다.일반적으로 조롱에는 몇 줄의 대사가 포함되어 있습니다.그 후에, 그 장면을 「설정」하고 나서, 당신이 준비한 모의 컨텍스트로 「전개」하는 방법을 호출합니다.풍경과 소품을 세팅하는 동안 배우들이 무대 왼쪽으로 들어가서 마음껏 연기하는 건 절대 원치 않아요.
하지만 이건 내 급여 수준을 훨씬 넘는...지나가는 모키토 대제사장들의 설명을 구합니다...
* "parameter"가 올바른 용어입니까?
스파이에게 문제를 일으킬 수 있는 또 하나의 시나리오는 스프링콩(스프링 테스트 프레임워크) 또는 테스트 중에 오브젝트를 프록시하는 다른 프레임워크를 테스트하는 경우입니다.
예
@Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
위의 코드에서는 Spring과 Mockito 모두 Monitoring Documents Repository 오브젝트를 프록시하려고 합니다만, Spring이 첫 번째이므로 find Monitoring Documents 메서드가 실제로 호출됩니다.저장소 개체에 스파이를 설치한 직후에 코드를 디버깅하면 다음과 같은 내부 디버거가 나타납니다.
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
@SpyBean 구조
' '일 경우'@Autowired
하는 주석@SpyBean
이 내부 . SpyBean 。 그러나 이것은 먼저 Mockito에 의해 프록시가 되며 디버거 내부와 같습니다.
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
코드는 다음과 같습니다.
@SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
중요한 건 진짜 물건을 염탐하는 거야
spy를 사용하여 메서드를 stubing할 때는 doReturn() 패밀리 메서드를 사용하십시오.
(오브젝트)가 예외를 발생시킬 수 있는 실제 메서드를 호출하는 경우.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
스파이가 원래 방법이라고 부르는 또 다른 이유를 찾았어요.
비웃을 .final
및 , 「 」에 대해서MockMaker
:
으로, 또 이 이 있기 에, 피드백을 이 하게 할 이 기능은, 파일 메카니즘에 할 수 .성화해야 합니다.파일을 작성함으로써 mockito 확장 메커니즘을 통해 실행할 수 있습니다.
src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
단일 행 포함:mock-maker-inline
출처 : https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
그 파일을 머지하여 머신에 가져온 후 테스트에 실패했습니다.
행(또는 파일)을 삭제하기만 하면 됩니다.spy()
일했다.
클래스의 메서드가 호출되지 않도록 하는 방법 중 하나는 메서드를 더미로 덮어쓰는 것입니다.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
@Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
코멘트 중 일부에서 언급했듯이, 내 메서드는 "static"(클래스의 인스턴스에 의해 호출되지만)이었다.
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
회피책으로는 인스턴스 메서드를 만들거나 Mockito를 몇 가지 설정을 가진 새로운 버전으로 업그레이드했습니다.https://stackoverflow.com/a/62860455/32453
파티에는 늦었지만 위의 해결방법은 효과가 없었기 때문에 0.02$를 공유합니다.
Mokcito 버전 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
다음 방법이 작동하지 않았습니다(실제 메서드가 호출되었습니다).
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
다음 작업:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());
언급URL : https://stackoverflow.com/questions/11620103/mockito-trying-to-spy-on-method-is-calling-the-original-method
'programing' 카테고리의 다른 글
vue 어플리케이션에서 Paypal 서브스크립션을 구현하려면 어떻게 해야 합니까? (0) | 2022.06.21 |
---|---|
Vue CLI 3으로 Vuetify를 설치한 후 컴파일하지 못함 (0) | 2022.06.21 |
Vue.js - 모델이 변경을 거부하는 경우 입력값 복원 (0) | 2022.06.20 |
C 프로그래밍 언어는 객체 지향입니까? (0) | 2022.06.20 |
AssertjUnit의 문자열에 포함됨 (0) | 2022.06.20 |