मॉकिटो किसी भी वर्ग तर्क से मेल खाता है


153

वहाँ नीचे नमूना दिनचर्या के किसी भी वर्ग तर्क मैच के लिए एक रास्ता है?

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

मैं हमेशा इस बात की new B()परवाह किए बिना लौट सकता हूं कि किस वर्ग में उत्तीर्ण हुआ method। निम्नलिखित प्रयास केवल उस विशिष्ट मामले के लिए काम करता है जहां Aमिलान किया जाता है।

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

संपादित करें : एक समाधान है

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

6

आपका (कक्षा <?>) कोई भी (Class.class) समाधान यहां उत्तर होना चाहिए। मैं इसके बजाय क्लासऑरेस्क्लाक्लासमैचर क्लास को नीचे देख सकता हूं।
सुपरबॉस्पेरम्पी

@superbAfterSemperPhi और johan-sjöberg मैंने ऐसा करने का एक और तरीका पोस्ट किया है, बिना कास्ट के। मेरा मानना ​​है कि यह एक बेहतर तरीका हो सकता है। तुम क्या सोचते हो?
शामिया

जवाबों:


188

इसे करने के दो और तरीके (मेरी टिप्पणी @Tomasz Nurkiewicz द्वारा पिछले उत्तर पर देखें):

पहला इस तथ्य पर निर्भर करता है कि संकलक आपको गलत प्रकार के कुछ में पारित नहीं होने देगा:

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

आप सटीक टाइपिंग खो देते हैं (a) 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)मेरे लिए चीजों को गड़बड़ करता है, इसलिए मैंने इसे हटा दिया।
डैनियल स्मिथ

क्लास के डिक्लेरेशन लाइन पर, मुझे extends BaseMatcher<Class<T>>बस बदलना पड़ा extends BaseMatcher<T>। सिर्फ FYI करें, अगर किसी और को संकलन संबंधी त्रुटियां मिलती हैं, तो उसे आज़माएं।
जन

मुझे matchesफ़ंक्शन को निम्न में भी बदलना पड़ा :public boolean matches(Object obj) { if (obj != null) { return targetClass.isAssignableFrom(obj.getClass()); } return false; }
Jan

कोई भी (क्लास.क्लास) अशक्त लौट रहा है - मैं अशक्त होने से कैसे बच सकता हूं
अरविंद कुमार

बहुत अच्छा होगा यदि वास्तव में उस वर्ग को जोड़ दें जो मुझे आयात करने की आवश्यकता है क्योंकि अब कई हैं "मॉकिटो से" कोई भी "
jpganz18

53

बिना कास्ट के ऐसा करने का एक और तरीका है:

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

यह समाधान विधि any()को वापस लौटने के लिए मजबूर करता है Class<A>न कि उसके डिफ़ॉल्ट मान ( Object) को।


5
Matchersमॉकिटो के नए संस्करणों में पदावनत किया गया है और संभवतः संस्करण 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
इससे मेरी जान बच गई, मैं गलती से हैमरेस्ट लाइब्रेरी से "कोई" आयात कर रहा था।
गागोर नेगी

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);
बजे

मेरे लिए दूसरा हिस्सा आकर्षण का काम करता है। किसी के साथ लड़ाई (SomeClass.class) एक मृत अंत के लिए नेतृत्व। लेकिन (SomeClass.class) notNull () ने मेरा दिन बचाया
वादिम

यदि आपके पास एक ही नाम के साथ दो विधियां हैं, लेकिन विभिन्न तर्क हैं तो आप यहां दूसरे संस्करण का उपयोग करते हुए मजाक उड़ाए जाने की विधि को अस्वीकार कर सकते हैं। पहले संस्करण ने इसे मेरे लिए (जावा 8 पर) नहीं काटा।
पटरू

धन्यवाद, isA (A.class) मेरे लिए ठीक काम करता है और mvcConversionService सही वर्ग का चयन करता है। यह किसी (A.class) और eq (A.class) के साथ काम नहीं कर रहा था।
d3rbastl3r

9

हाल के संस्करण के साथ मिलहाउस से समाधान अब काम नहीं कर रहा है

यह समाधान जावा 8 और मॉकिटो 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);

Instof हालत अब आवश्यक नहीं है, और मैंने एक सुविधा पद्धति लिखी:public static <T> Class<T> subClassOf(Class<T> targetClass) { return argThat(new ClassOrSubclassMatcher<>(targetClass)); }
डैनियल एल्डर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.