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.