source

모키토.메서드 인수 확인

goodcode 2022. 8. 15. 21:09
반응형

모키토.메서드 인수 확인

나는 이것에 대해 검색해 보았지만, 관련된 것을 찾지 못했다.나한테는 이런게 있어.

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj )).thenReturn(null);

Testeable testableObj = new Testeable();
testableObj.setMockeable(mock);
command.runtestmethod();

그럼 제가 하겠습니다.mymethod(Object o)에 있는 을 안쪽이라고 runtestmethod()는 오브젝트를 o합니다. 다음과 같이 치릅니다.이치 예를 들어, 다음과 같은 조건을 충족합니다.

Mockito.verify(mock.mymethod(Mockito.eq(obj)));

또는

Mockito.verify(mock.mymethod(Mockito.eq(null)));

또는

Mockito.verify(mock.mymethod(Mockito.eq("something_else")));

나는 항상 시험에 합격한다.그 검증(가능한 경우)은 어떻게 하면 됩니까?

감사합니다.

「 」의 ArgumentMatcher는 입니다.

공식 예:

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());

캡터는 @Captor 주석을 사용하여 정의할 수도 있습니다.

@Captor ArgumentCaptor<Person> captor;
//... MockitoAnnotations.initMocks(this);
@Test public void test() {
    //...
    verify(mock).doSomething(captor.capture());
    assertEquals("John", captor.getValue().getName());
}

객체의 .equals 메서드를 사용하여 논리적 동등성을 수행하려고 합니까?Mockito에 포함된 argThat matcher를 사용하여 수행할 수 있습니다.

import static org.mockito.Matchers.argThat

다음으로 각 오브젝트의 .equals 메서드에 따르는 독자적인 인수 매처를 구현할 수 있습니다.

private class ObjectEqualityArgumentMatcher<T> extends ArgumentMatcher<T> {
    T thisObject;

    public ObjectEqualityArgumentMatcher(T thisObject) {
        this.thisObject = thisObject;
    }

    @Override
    public boolean matches(Object argument) {
        return thisObject.equals(argument);
    }
}

이제 코드를 사용하여 코드를 업데이트하여 읽을 수 있습니다.

Object obj = getObject();
Mockeable mock= Mockito.mock(Mockeable.class);
Mockito.when(mock.mymethod(obj)).thenReturn(null);

Testeable obj = new Testeable();
obj.setMockeable(mock);
command.runtestmethod();

verify(mock).mymethod(argThat(new ObjectEqualityArgumentMatcher<Object>(obj)));

(메모리의 같은 오브젝트) 완전 평등을 목표로 하는 경우는, 다음과 같이 해 주세요.

verify(mock).mymethod(obj);

한 번 호출된 것을 확인합니다.

argThat 람다

이렇게 하면 인수 검증에 실패할 수 있습니다.

    verify(mock).mymethod(argThat(
                            x -> false ));

어디에

import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.verify;

argThat 단언

는 '말하다' 입니다Expected: lambda$... Was: YourClass.toSting...lamda의 을 얻을 수

    verify(mock).mymethod(argThat( x -> {
      assertThat(x).isNotNull();
      assertThat(x.description).contains("KEY");
      return true;
    }));

❗(BUT❗)이 동작하는 것은, 다음의 경우 입니다.

  • 콜은 1회 또는 1회 예정
  • 2회가 일치하는 모든 (「2」)입니다.true를 참조해 주세요.

검증된 메서드가 2회 이상 호출된 경우 mockito는 모든 호출된 조합을 각 검증자에게 전달합니다.따라서 mockito는 검증자가 인수 세트하나에 대해 자동으로 반환되기를 기대합니다.false(아소트 예외 없음) 다른 유효한 콜을 클릭합니다.이 예상은 1개의 메서드콜에 문제가 되지 않습니다.참말

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.verify;

불합격자는 이렇게 Expected: Obj.description to contain 'KEY'. Was: 'Actual description'assertJ단, 어떤 단언 프레임워크를 사용할지는 사용자에게 달려 있습니다.


직접 논거

는 Mokito를 사용하여 합니다.equals():

verify(mock).mymethod(expectedArg);
// NOTE:   ^ where the parentheses must be closed.

eq

  • 사용하지 .eqarg 한 개에 대해서요.앞에서 언급한 직접 논거를 사용합니다.
  • 는 Mokito를 사용하여 합니다.equals()
  • eqSonarQube / SonarClound 위반일 수 있습니다.https://rules.sonarsource.com/java/tag/mockito/RSPEC-6068

argThat여러 개의 인수를 사용합니다.

「 」를 사용하고 argThat모든 인수에는 일치 항목을 지정해야 합니다.예: 다른 경우, 두 개의 인수를 가진 다른 메서드가 있는 경우:

    verify(mock).mymethod2(eq("VALUE_1"), argThat((x)->false));
    // above is correct as eq() is also an argument matcher.

verify(mock).mymethod2("VALUE_1", argThat((x)->false));

// above is incorrect; an exception will be thrown, as the first arg. is given without an argument matcher.

여기서:

import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;

원래 질문 실패의 근본 원인은 괄호 위치가 잘못되었기 때문입니다.

  • 그건 틀렸어verify(mock.mymethod....오른쪽은 다음과 같습니다.
  • verify(mock).*
  • 필요 없어요.eq다른 매튜어를 사용하지 않을 경우 매튜어를 사용합니다.
  • 올바른 구문을 사용하고 있지 않습니다.메서드 호출은,.verify(mock)여기서 메서드 콜의 결과에 대한 검증을 시작합니다(메서드 콜을 발신하지 않음).따라서 모든 테스트는 합격입니다.

코드는 다음과 같습니다.

Mockito.verify(mock).mymethod(obj);
Mockito.verify(mock).mymethod(null);
Mockito.verify(mock).mymethod("something_else");

나는 모키토를 사용한 적이 있다.이렇게 검증하다

@UnitTest
public class JUnitServiceTest
{
    @Mock
    private MyCustomService myCustomService;


    @Test
    public void testVerifyMethod()
    {
       Mockito.verify(myCustomService, Mockito.never()).mymethod(parameters); // method will never call (an alternative can be pick to use times(0))
       Mockito.verify(myCustomService, Mockito.times(2)).mymethod(parameters); // method will call for 2 times
       Mockito.verify(myCustomService, Mockito.atLeastOnce()).mymethod(parameters); // method will call atleast 1 time
       Mockito.verify(myCustomService, Mockito.atLeast(2)).mymethod(parameters); // method will call atleast 2 times
       Mockito.verify(myCustomService, Mockito.atMost(3)).mymethod(parameters); // method will call at most 3 times
       Mockito.verify(myCustomService, Mockito.only()).mymethod(parameters); //   no other method called except this
    }
}

모의고사 수업의 동등한 방법을 확인해 보셨나요?이 값이 항상 true를 반환하거나 동일한 인스턴스에 대해 동일한 인스턴스를 테스트하고 동일한 메서드를 덮어쓰지 않으면(이 때문에 참조에 대해서만 체크), true를 반환합니다.

다른 방법은 org.mockito를 사용하는 것입니다.internal.matcers.Equals. 1을 재정의하는 대신 Equals 메서드를 사용합니다.

verify(myMock).myMethod((inputObject)Mockito.argThat(new Equals(inputObjectWanted)));

위의 답변 중 많은 부분이 혼란스러웠지만, 아마도 오래된 버전의 모키토 때문일 것입니다.이 답변은 다음 방법으로 이루어집니다.

  • 자바 11
  • 모키토 3.1.0
  • Spring Boot 2.2.7풀어주다
  • JUnit5

Argument Captor를 사용하여 다음과 같이 처리했습니다.

@Mock
MyClientService myClientService;
@InjectMocks 
MyService myService;


@Test
void myTest() {

  ArgumentCaptor<String> captorParam1 = ArgumentCaptor.forClass(String.class);
  ArgumentCaptor<String> captorParam2 = ArgumentCaptor.forClass(String.class);

  Mockito.when(myClientService.doSomething(captorParam1.capture(), captorParam2.capture(), ArgumentMatchers.anyString()))
      .thenReturn(expectedResponse);

  assertDoesNotThrow(() -> myService.process(data));

  assertEquals("param1", captorParam1.getValue());
  assertEquals("param2", captorParam2.getValue());

  verify(myClientService, times(1))
    .doSomething(anyString(), anyString(), anyString());
}

same() matcher와 시험해 본 적이 있습니까?예:

verify(mockObj).someMethod(same(specificInstance));

저도 같은 문제가 있었어요.eq() 매처와 refEq() 매처와 함께 시도했지만 항상 false positive가 있었습니다.same() matcher를 사용하면 인수가 다른 인스턴스일 때 테스트가 실패하고 인수가 같은 인스턴스일 때 통과했습니다.

Verify(a).aFunc(eq(b))

의사 코드:

인스턴스의 경우a- 함수 이름aFunc호출됩니다.

이 콜에 다음과 같은 인수가 있는지 확인합니다.b.

Type Safe Diagnosting Matcher를 사용할 수도 있습니다.

    private Matcher<GetPackagesRequest> expectedPackageRequest(final AvailabilityRequest request) {
    return new TypeSafeDiagnosingMatcher<GetPackagesRequest>() {

        StringBuilder text = new StringBuilder(500);

        @Override
        protected boolean matchesSafely(GetPackagesRequest req, Description desc) {
            String productCode = req.getPackageIds().iterator().next().getValue();
            if (productCode.equals(request.getSupplierProductCode())) {
                text.append("ProductCode not equal! " + productCode + " , " + request.getSupplierProductCode());
                return true;
            }

            text.append(req.toString());
            return false;
        }

        @Override
        public void describeTo(Description d) {
            d.appendText(text.toString());
        }
    };
}

다음에, 다음의 호출을 확인합니다.

Mockito.verify(client).getPackages(Mockito.argThat(expectedPackageRequest(request)));

언급URL : https://stackoverflow.com/questions/3555472/mockito-verify-method-arguments

반응형