Mockito는 모든 클래스 인수와 일치


153

아래 샘플 루틴의 클래스 인수와 일치하는 방법이 있습니까?

class A {
     public B method(Class<? extends A> a) {}
}

어떤 클래스가 전달되는지에 관계없이 항상 어떻게 반환 할 수 있습니까? 다음 시도 는 일치 하는 특정 사례에만 적용됩니다 .new B()methodA

A a = new A();
B b = new B();
when(a.method(eq(A.class))).thenReturn(b);

편집 : 하나의 해결책은

(Class<?>) any(Class.class)

6
Class<?>놀랄 만한!
António Almeida

귀하의 (Class <?>) any (Class.class) 솔루션이 여기에 답이되어야합니다. 아래에서 본 ClassOrSubclassMatcher 클래스를 사용하는 것이 좋습니다.
superbAfterSemperPhi

@ superbAfterSemperPhi와 johan-sjöberg 나는 캐스팅하지 않고 다른 방법을 게시했습니다. 나는 그것이 더 좋은 방법 일 수 있다고 생각합니다. 어떻게 생각해?
anmaia

답변:


188

두 가지 방법으로 더 할 수 있습니다 (@Tomasz Nurkiewicz의 이전 답변에 대한 내 의견 참조).

첫 번째는 컴파일러가 단순히 잘못된 유형의 무언가를 전달할 수 없다는 사실에 의존합니다.

when(a.method(any(Class.class))).thenReturn(b);

정확한 타이핑 ( Class<? extends A>)을 잃어 버렸지 만 필요에 따라 작동 할 것입니다.

두 번째는 훨씬 더 복잡하지만,이 경우 틀림없이 더 나은 솔루션을 정말 확실 인수가가되고 싶어 method()입니다 A또는 서브 클래스의를 A:

when(a.method(Matchers.argThat(new ClassOrSubclassMatcher<A>(A.class)))).thenReturn(b);

어디 ClassOrSubclassMatcher되어 org.hamcrest.BaseMatcher정의 :

public class ClassOrSubclassMatcher<T> extends BaseMatcher<Class<T>> {

    private final Class<T> targetClass;

    public ClassOrSubclassMatcher(Class<T> targetClass) {
        this.targetClass = targetClass;
    }

    @SuppressWarnings("unchecked")
    public boolean matches(Object obj) {
        if (obj != null) {
            if (obj instanceof Class) {
                return targetClass.isAssignableFrom((Class<T>) obj);
            }
        }
        return false;
    }

    public void describeTo(Description desc) {
        desc.appendText("Matches a class or subclass");
    }       
}

휴! 당신이 때까지 나는 첫 번째 옵션과 함께 가고 싶어 정말 무엇을 통해 세밀하게 제어를 얻을 필요가 method()실제로 돌아갑니다 :-)


if (obj instanceof Class)나를 위해 놨 물건까지, 그래서 나는 그것을 제거.
Daniel Smith

클래스의 선언 줄에서 나는로 변경 extends BaseMatcher<Class<T>>해야했습니다 extends BaseMatcher<T>. 참고로 다른 사람이 컴파일 오류가 발생하면 시도해보십시오.
Jan

또한 matches기능을 다음과 같이 변경해야했습니다 .public boolean matches(Object obj) { if (obj != null) { return targetClass.isAssignableFrom(obj.getClass()); } return false; }
Jan

any (Class.class)가 null을 반환합니다. null을 반환하지 않으려면 어떻게해야합니까
Arvind Kumar

실제로 지금 "어떤"mockito 많은입니다 I 가져 오기에 필요하기 때문에 클래스 추가하면 좋을 것
jpganz18

53

캐스트하지 않고 다른 방법으로 수행 할 수 있습니다.

when(a.method(Matchers.<Class<A>>any())).thenReturn(b);

이 솔루션은 메서드 any()Class<A>기본값 ( Object)이 아닌 형식 을 반환하도록 합니다 .


5
MatchersMockito의 최신 버전에서는 더 이상 사용되지 않으며 3.0 버전에서 제거 될 수 있습니다. ArgumentMatchers대신 사용하십시오 :when(a.method(ArgumentMatchers.<Class<A>>any())).thenReturn(b);
Voicu

41

어떤 패키지를 가져와야할지 모른다면 :

import static org.mockito.ArgumentMatchers.any;
any(SomeClass.class)

또는

import org.mockito.ArgumentMatchers;
ArgumentMatchers.any(SomeClass.class)

13
이것은 내 생명을 구했습니다. 우연히 hamcrest 라이브러리에서 "any"를 가져 왔습니다.
Gábor Nagy

3
이제 변경되었습니다org.mockito.ArgumentMatchers.any
BOWS

27

어때요?

when(a.method(isA(A.class))).thenReturn(b);

또는:

when(a.method((A)notNull())).thenReturn(b);

4
메소드 서명이 method(A a)-(효과적으로) method(Class<A> a)-그렇다면 다음을 사용해야합니다. when(a.method(isA(Class.class))).thenReturn(b);또는when(a.method((Class<A>) notNull())).thenReturn(b);
millhouse

나를 위해 두 번째 부분은 매력으로 작동합니다. (SomeClass.class)와 싸우면 막 다른 길로 이어집니다. 그러나 (SomeClass.class) notNull ()은 내 하루를 구했습니다
Vadim

이름은 같지만 인수가 다른 두 개의 메소드가있는 경우 여기에서 두 번째 버전을 사용하여 메소드를 조롱 할 수 있습니다. 첫 번째 버전은 나를 위해 그것을 자르지 않았습니다 (Java 8에서).
Patru

감사합니다, isA (A.class)는 저에게 잘 작동하며 mvcConversionService는 올바른 클래스를 선택합니다. 이것은 (A.class) 및 eq (A.class)에서 작동하지 않았습니다.
d3rbastl3r

9

millhouse의 솔루션이 더 이상 최신 버전의 mockito에서 작동하지 않습니다.

이 솔루션은 Java 8 및 mockito 2.2.9에서 작동합니다.

ArgumentMatcher인스턴스는 어디에 있습니까org.mockito.ArgumentMatcher

public class ClassOrSubclassMatcher<T> implements ArgumentMatcher<Class<T>> {

   private final Class<T> targetClass;

    public ClassOrSubclassMatcher(Class<T> targetClass) {
        this.targetClass = targetClass;
    }

    @Override
    public boolean matches(Class<T> obj) {
        if (obj != null) {
            if (obj instanceof Class) {
                return targetClass.isAssignableFrom( obj);
            }
        }
        return false;
    }
}

그리고 사용

when(a.method(ArgumentMatchers.argThat(new ClassOrSubclassMatcher<>(A.class)))).thenReturn(b);

instanceof 조건은 더 이상 필요하지 않으며 편리한 방법을 작성했습니다.public static <T> Class<T> subClassOf(Class<T> targetClass) { return argThat(new ClassOrSubclassMatcher<>(targetClass)); }
Daniel Alder
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.