programing

Mockito에서 미완성 스터빙이 탐지됨

prostudy 2022. 5. 24. 21:53
반응형

Mockito에서 미완성 스터빙이 탐지됨

나는 시험을 보는 동안 예외를 받고 있다.나는 조롱하기 위해 모키토를 사용하고 있다.모키토 도서관이 언급한 힌트는 도움이 되지 않는다.

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
    -> at com.a.b.DomainTestFactory.myTest(DomainTestFactory.java:355)

    E.g. thenReturn() may be missing.
    Examples of correct stubbing:
        when(mock.isOk()).thenReturn(true);
        when(mock.isOk()).thenThrow(exception);
        doThrow(exception).when(mock).someVoidMethod();
    Hints:
     1. missing thenReturn()
     2. you are trying to stub a final method, you naughty developer!

        at a.b.DomainTestFactory.myTest(DomainTestFactory.java:276)
        ..........

테스트 코드 위치DomainTestFactory.다음 테스트를 실행하면 예외를 본다.

@Test
public myTest(){
    MyMainModel mainModel =  Mockito.mock(MyMainModel.class);
    Mockito.when(mainModel.getList()).thenReturn(getSomeList()); // Line 355
}

private List<SomeModel> getSomeList() {
    SomeModel model = Mockito.mock(SomeModel.class);
    Mockito.when(model.getName()).thenReturn("SomeName"); // Line 276
    Mockito.when(model.getAddress()).thenReturn("Address");
    return Arrays.asList(model);
}

public class SomeModel extends SomeInputModel{
    protected String address;
    protected List<SomeClass> properties;

    public SomeModel() {
        this.Properties = new java.util.ArrayList<SomeClass>(); 
    }

    public String getAddress() {
        return this.address;
    }

}

public class SomeInputModel{

    public NetworkInputModel() {
        this.Properties = new java.util.ArrayList<SomeClass>(); 
    }

    protected String Name;
    protected List<SomeClass> properties;

    public String getName() {
        return this.Name;
    }

    public void setName(String value) {
        this.Name = value;
    }
}

너는 조롱의 내면에 비웃음을 품고 있다.전화했구나getSomeList()에 대한 조롱을 끝내기 전에, 그것은 약간 조롱하는 것이다.MyMainModel모키토는 이런 거 싫어해.

대체하다

@Test
public myTest(){
    MyMainModel mainModel =  Mockito.mock(MyMainModel.class);
    Mockito.when(mainModel.getList()).thenReturn(getSomeList()); --> Line 355
}

와 함께

@Test
public myTest(){
    MyMainModel mainModel =  Mockito.mock(MyMainModel.class);
    List<SomeModel> someModelList = getSomeList();
    Mockito.when(mainModel.getList()).thenReturn(someModelList);
}

이것이 왜 문제를 일으키는지 이해하기 위해서는 모키토가 어떻게 작동하는지 조금 알아야 하며, 자바에서 어떤 순서로 표현과 문장이 평가되는지 알아야 한다.

모키토는 당신의 소스 코드를 읽을 수 없기 때문에, 당신이 무엇을 요구하는지 알아내기 위해, 그것은 정적 상태에 많이 의존한다.모키토는 모의 객체에 메서드를 호출할 때 호출의 세부사항을 내부 호출 목록에 기록한다.when메소드는 이러한 호출 중 마지막을 목록에서 읽고 이 호출을 에 기록한다.OngoingStubbing그것이 반환되는 것을 반대하다

라인

Mockito.when(mainModel.getList()).thenReturn(someModelList);

모키토와 다음과 같은 상호작용을 일으킨다.

  • 모의법mainModel.getList()라고 불린다.
  • 정적법when라고 불린다.
  • 방법thenReturn에 소집되다OngoingStubbing에 의해 반환된 물건when방법의

thenReturn그런 다음 메소드는 다음을 통해 받은 모의실험을 지시할 수 있다.OngoingStubbing에 대한 적절한 호출을 처리하는 방법getList반환 방법someModelList.

사실 모키토는 당신의 코드를 볼 수 없기 때문에 다음과 같이 조롱의 글을 쓸 수도 있다.

mainModel.getList();
Mockito.when((List<SomeModel>)null).thenReturn(someModelList);

이 문체는 읽기에 다소 명확하지 않다. 특히 이 경우,null주조되어야 하지만, 모키토와 동일한 순서의 상호작용을 생성하며, 위의 선과 동일한 결과를 얻을 것이다.

하지만, 그 선은

Mockito.when(mainModel.getList()).thenReturn(getSomeList());

모키토와 다음과 같은 상호작용을 일으킨다.

  1. 모의법mainModel.getList()라고 불린다.
  2. 정적법when라고 불린다.
  3. A newmockSomeModel생성됨(생성됨getSomeList()),
  4. 모의법model.getName()라고 불린다.

이때 모키토는 혼란스러워한다.네가 비웃는 줄 알았는데mainModel.getList()하지만 지금 당신은 그것을 조롱하고 싶다고 말하고 있다.model.getName()방법의모키토에게는 다음과 같은 행동을 하고 있는 것 같다.

when(mainModel.getList());
// ...
when(model.getName()).thenReturn(...);

이 일은 에게 어리석게 보인다.Mockito당신이 무엇을 하고 있는지 확실하지 않기 때문에mainModel.getList().

우리가 도착하지 않았다는 것에 주목하라.thenReturn메서드 호출, JVM은 메서드를 호출하기 전에 이 메서드에 대한 파라미터를 평가해야 하기 때문이다.이 경우, 이는 곧 '''라고 부르는 것을 의미한다.getSomeList()방법의

일반적으로 모키토와 같이 정적 상태에 의존하는 것은 나쁜 설계 결정으로, 이는 최소 아스톤의 원칙을 위반하는 경우를 초래할 수 있기 때문이다.하지만, 모키토의 디자인은 때때로 놀라움으로 이어질지라도 분명하고 표현적인 조롱을 만들어낸다.

마지막으로, Mockito의 최근 버전은 위의 오류 메시지에 추가 라인을 추가한다.이 추가 라인은 다음과 같은 질문과 동일한 상황에 있을 수 있음을 나타낸다.

3: 완료된 경우 'the Return' 명령 전에 내부에서 또 다른 모의 실행의 동작을 스텁하는 경우

사용하시는 분들을 위해서.com.nhaarman.mockitokotlin2.mock {}

해결 방법 1

이 오류는 예를 들어, 우리가 다른 모의실험에 모의실험을 만들 때 발생한다.

mock {
    on { x() } doReturn mock {
        on { y() } doReturn z()
    }
}

이에 대한 해결책은 변수에서 자식 모의실험을 만들고 부모 모의실험의 범위에서 변수를 사용하여 모의생성이 명시적으로 내포되지 않도록 하는 것이다.

val liveDataMock = mock {
        on { y() } doReturn z()
}
mock {
    on { x() } doReturn liveDataMock
}

해결 방법 2

당신의 모든 조롱은 반드시 다음이 있어야 한다.thenReturn가 있다thenReturn.

GL

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here:
E.g. thenReturn() may be missing.

보이드 방법을 조롱하려면 다음을 시도해 보십시오.

//Kotlin Syntax

 Mockito.`when`(voidMethodCall())
           .then {
                Unit //Do Nothing
            }

AbcService abcService = mock(AbcService.class);

구문을 확인하십시오.

  1. doThrow(new RunTimeException()).when(abcService).add(any(), any())

아래 보이는 일반적인 실수:

. AdoThrow(new RunTimeException()).when(abcService.add(any(), any()))

마찬가지로 언제()를 확인한 다음 반환()을 확인하십시오.

기사를 읽어보십시오. 이 기사는 특별한 설명과 작업 접근법을 담고 있다.또한 이러한 문제와 해결책이 해결되는 또 하나의 가능한 이유는 실제 조롱을 시험의 초기 단계로 옮기기 위함이다.

나는 @Luke Woodward의 상세한 대답에 너무 흥분해서 해결 방법을 공유하고 싶다.@Luke Woodward가 설명했듯이 우리는 다음과 같은 전화를 두 번 할 수 없다.

when(mainModel.getList());
// ...
when(model.getName()).thenReturn(...);

콜 체인에서 일어날 수 있다.그러나 공정을 사용할 경우:

doReturn(mockToken("token3")).when(mock).getAccessToken();

할 때

OAuth2AccessToken mockToken(String tokenVal){
        OAuth2AccessToken token = Mockito.mock(OAuth2AccessToken.class);
        doReturn( 60 ).when(token).getExpiresIn();
        doReturn(tokenVal).when(token).getValue();
        return token;
    }

모든 것이 예상대로 될 것이다.

참조URL: https://stackoverflow.com/questions/26318569/unfinished-stubbing-detected-in-mockito

반응형