Mockito herhangi bir sınıf argümanıyla eşleşir


153

Aşağıdaki örnek rutinin herhangi bir sınıf argümanını eşleştirmenin bir yolu var mı?

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

Hangi sınıfa geçilmiş olursa olsun her zaman nasıl geri dönebilirim ? Aşağıdaki deneme yalnızca eşleşen belirli vaka için geçerlidir .new B()methodA

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

EDIT : Bir çözüm

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

6
Class<?>inanılmaz!
António Almeida

(Class <?>) Herhangi bir (Class.class) çözümünüz burada yanıt olmalıdır. Çok daha sonra aşağıda görülen ClassOrSubclassMatcher sınıfını kullanmak istiyorum.
superbAfterSemperPhi

@superbAfterSemperPhi ve johan-sjöberg Bunu yapmanın başka bir yolunu yayınlamadan yayınladım. Bunun daha iyi bir yol olabileceğine inanıyorum. Ne düşünüyorsun?
anmaia

Yanıtlar:


188

Bunu yapmanın iki yolu daha (@Tomasz Nurkiewicz tarafından verilen önceki yanıt hakkındaki yorumuma bakın):

Birincisi, derleyicinin yanlış türde bir şeyden geçmenize izin vermemesine dayanır:

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

Tam yazmayı (the Class<? extends A>) kaybedersiniz, ancak muhtemelen ihtiyacınız olduğu gibi çalışır.

İkinci çok daha fazla yer ama eğer tartışmalı daha iyi bir çözüm gerçekten emin argüman o olmak istiyorum method()bir olan Aveya bir alt ait A:

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

Nerede ClassOrSubclassMatcherşu şekilde org.hamcrest.BaseMatchertanımlanır:

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");
    }       
}

Uf! Gerçekten ne method()döner üzerinde daha ince kontrol almak gerekir kadar ilk seçenek ile gitmek istiyorum :-)


if (obj instanceof Class)Benim için messes şeyler yukarı, bu yüzden kaldırıldı.
Daniel Smith

Sınıfın deklarasyon satırında extends BaseMatcher<Class<T>>adil olarak değişmek zorunda kaldım extends BaseMatcher<T>. Sadece FYI, eğer birisi derleme hataları alırsa, bunu deneyin.
Ocak

Ben de değiştirmek zorunda matchesaşağıdakilere fonksiyonu:public boolean matches(Object obj) { if (obj != null) { return targetClass.isAssignableFrom(obj.getClass()); } return false; }
Jan

any (Class.class) null döndürüyor - null dönmek nasıl önleyebilirim
Arvind Kumar

Eğer gerçekten o zamandan beri ithal etmek gerekir sınıf eklemek harika olurdu mockito gelen birçok "herhangi"
jpganz18

53

Döküm yapmadan bunu yapmanın başka bir yolu var:

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

Bu çözüm, yöntemi varsayılan değeri ( ) yerine tür any()döndürmeye zorlar .Class<A>Object


5
MatchersMockito'nun yeni sürümlerinde kullanımdan kaldırılmıştır ve muhtemelen 3.0 sürümünde kaldırılacaktır. ArgumentMatchersBunun yerine kullanın :when(a.method(ArgumentMatchers.<Class<A>>any())).thenReturn(b);
Voicu

41

Hangi Paketi içe aktarmanız gerektiğine dair bir fikriniz yoksa:

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

VEYA

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

13
Bu hayatımı kurtardı, yanlışlıkla hamcrest kütüphanesinden "herhangi" ithal ediyorum.
Gábor Nagy

3
Şimdi değiştiorg.mockito.ArgumentMatchers.any
BOWS

27

Nasıl olur:

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

veya:

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

4
Bunlar, yöntem imzası method(A a)- ancak (etkili bir şekilde) method(Class<A> a)- olsaydı when(a.method(isA(Class.class))).thenReturn(b);when(a.method((Class<A>) notNull())).thenReturn(b);
derlenir

benim için ikinci bölüm cazibe olarak çalışıyor. Herhangi bir (SomeClass.class) ile kavga çıkmaz bir yol. Ancak (SomeClass.class) notNull () günümü kurtardı
Vadim

Aynı ada sahip ancak farklı argümanlara sahip iki yönteminiz varsa, buradaki ikinci sürümü kullanarak alay edilecek yöntemi belirsizleştirebilirsiniz. İlk sürüm benim için kesmedi (Java 8'de).
Patru

Teşekkürler, isA (A.class) benim için iyi çalışıyor ve mvcConversionService doğru sınıfı seçin. Bu, herhangi bir (A.class) ve eq (A.class) ile çalışmıyordu.
d3rbastl3r

9

Millhouse çözümü artık mockito'nun son sürümü ile çalışmıyor

Bu çözüm Java 8 ve Mockito 2.2.9 ile çalışır

nerede ArgumentMatcherbir örnekorg.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;
    }
}

Ve kullanımı

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

instanceof koşulu artık gerekli değil ve bir kolaylık yöntemi yazdım:public static <T> Class<T> subClassOf(Class<T> targetClass) { return argThat(new ClassOrSubclassMatcher<>(targetClass)); }
Daniel Alder
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.