Deux autres façons de le faire (voir mon commentaire sur la réponse précédente de @Tomasz Nurkiewicz) :
La première repose sur le fait que le compilateur ne vous laissera tout simplement pas passer quelque chose de mauvais type :
when(a.method(any(Class.class))).thenReturn(b);
Vous perdez le typage exact (le Class<? extends A>
) mais cela fonctionne probablement comme vous le souhaitez.
La seconde est beaucoup plus complexe, mais c'est sans doute la meilleure solution si vous souhaitez vraiment veulent être sûrs que l'argument de method()
est un A
ou une sous-classe de A
:
when(a.method(Matchers.argThat(new ClassOrSubclassMatcher<A>(A.class)))).thenReturn(b);
Où ClassOrSubclassMatcher
est un org.hamcrest.BaseMatcher
défini comme suit :
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");
}
}
Ouf ! J'opterais pour la première option jusqu'à ce que vous vraiment besoin d'avoir un contrôle plus fin sur ce que method()
retourne effectivement :-)
9 votes
Class<?>
incroyable !0 votes
Votre solution (Class<?>) any(Class.class) devrait être la réponse ici. Je préférerais de loin utiliser cette solution plutôt que la classe ClassOrSubclassMatcher vue ci-dessous.
0 votes
@superbAfterSemperPhi et johan-sjöberg J'ai posté une autre façon de faire cela, sans casting. Je pense que cela pourrait être une meilleure façon. Qu'en pensez-vous ?