মকিতো যেকোন শ্রেণীর যুক্তির সাথে মেলে


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<?>আশ্চর্যজনক!
আন্তোনিও আলমেডা

আপনার (শ্রেণি <?>) যেকোন (Class.class) সমাধানের উত্তরটি হওয়া উচিত। আমি তার চেয়ে অনেক বেশি ব্যবহার করব তবে নীচে দেখানো ক্লাসঅরসক্লাসম্যাচার ক্লাস।
superbAfterSemperPhi

@ সুপেরএফটারসেম্পারফি এবং জোহান-সিজবার্গ আমি কাস্টিং ছাড়াই এটি করার অন্য একটি উপায় পোস্ট করেছি। আমি বিশ্বাস করি যে এটি আরও ভাল উপায় হতে পারে। আপনি কি মনে করেন?
13:37

উত্তর:


188

এটি করার আরও দুটি উপায় (@ টমাসজ নুরকিউইকসের পূর্ববর্তী উত্তরের বিষয়ে আমার মন্তব্য দেখুন):

প্রথমটি নির্ভর করে যে সংকলকটি কেবল আপনাকে ভুল ধরণের কিছুতে পাস করতে দেয় না:

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)আমার জন্য messes জিনিষ আপ, তাই আমি এটা সরানো হয়েছে।
ড্যানিয়েল স্মিথ

ক্লাসের ডিক্লারেশন লাইনে আমাকে ন্যায়বিচারে পরিবর্তন extends BaseMatcher<Class<T>>করতে হয়েছিল extends BaseMatcher<T>। শুধু এফওয়াইআই, অন্য কারও যদি সংকলন ত্রুটি পায় তবে এটি চেষ্টা করে দেখুন।
জানুয়ারি

আমিও পরিবর্তন করতে হয়েছিল matches: নিম্নোক্ত ফাংশনpublic boolean matches(Object obj) { if (obj != null) { return targetClass.isAssignableFrom(obj.getClass()); } return false; }
জানুয়ারী

যে কোনও (শ্রেণি.ক্লাস) নাল ফিরছে - আমি কীভাবে নাল ফিরিয়ে এড়াতে পারি
অরবিন্দ কুমার

আমার এখন যে ক্লাসটি আমদানি করা দরকার সেগুলি যুক্ত করলে এখনই মকিতো থেকে অনেক "যে কোনও"
jpganz18

53

Castালাই ছাড়াই এটি করার আরও একটি উপায় রয়েছে:

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);
ভোকিক

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);
মিলহাউস

আমার জন্য দ্বিতীয় অংশ কবজ হিসাবে কাজ করে। যে কোনও (সামারগ্লাস.ক্লাস) সাথে লড়াই করার ফলে একটি মৃত পরিণতি হয়। তবে (সোমস্লাস.ক্লাস) নোট () আমার দিনটি সংরক্ষণ করেছে
ভাদিম

যদি আপনার একই নামের দুটি ভিন্ন পদ্ধতি রয়েছে তবে ভিন্ন ভিন্ন যুক্তি আপনি এখানে দ্বিতীয় সংস্করণ ব্যবহার করে ঠাট্টা-বিদ্রূপ করার পদ্ধতিটি অস্বীকার করতে পারেন। প্রথম সংস্করণটি এটি আমার জন্য কাটেনি (জাভা 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);

উদাহরণস্বরূপ শর্তটি আর প্রয়োজন হয় না, এবং আমি একটি সুবিধার পদ্ধতি লিখেছিলাম:public static <T> Class<T> subClassOf(Class<T> targetClass) { return argThat(new ClassOrSubclassMatcher<>(targetClass)); }
ড্যানিয়েল অ্যাল্ডার
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.