programing

모키토:메서드를 감시하는 것은 원래 메서드를 호출하는 것입니다.

prostudy 2022. 6. 21. 22:18
반응형

모키토:메서드를 감시하는 것은 원래 메서드를 호출하는 것입니다.

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.둘다staticMatchersnull아마 그 일 것이다.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

반응형