জেনেরিক পরামিতি সহ মকিতো ক্লাসগুলিতে মকিতো ব্যবহার করা


280

জেনেরিক পরামিতি সহ কোনও শ্রেণি উপহাস করার কি কোনও পরিষ্কার পদ্ধতি আছে? বলুন যে আমাকে এমন একটি ক্লাসের উপহাস Foo<T>করতে হবে যা আমাকে এমন পদ্ধতিতে পাস করতে হবে যা প্রত্যাশা করে Foo<Bar>। আমি নিম্নলিখিতগুলি সহজেই যথেষ্ট করতে পারি:

Foo mockFoo = mock(Foo.class);
when(mockFoo.getValue).thenReturn(new Bar());

ধরে নেওয়া getValue()জেনেরিক ধরণটি প্রদান করে T। কিন্তু বিড়ালছানা থাকবে যখন আমি পরে এটি প্রত্যাশা পদ্ধতিতে পাস করি Foo<Bar>। কাস্টিং কি এটি করার একমাত্র মাধ্যম?

উত্তর:


280

আমার মনে হয় আপনার এটি নিক্ষেপ করার দরকার আছে তবে এটি খুব খারাপ হওয়া উচিত নয়:

Foo<Bar> mockFoo = (Foo<Bar>) mock(Foo.class);
when(mockFoo.getValue()).thenReturn(new Bar());

34
হ্যাঁ তবে আপনার কাছে এখনও একটি সতর্কতা রয়েছে। সতর্কতা এড়ানো সম্ভব?
বিজয়

12
@ সাপ্রেস ওয়ার্নিংস ("চেক না করা")
কোয়েডাফিয়াল

18
আমি মনে করি এটি পুরোপুরি গ্রহণযোগ্য কারণ আমরা একটি ইউনিট পরীক্ষায় একটি মক অবজেক্টের কথা বলছি।
ম্যাগনাইলেক্স

1
@demanak এটি মোটেও কাজ করে না। যুক্তি ম্যাথার্স সেই প্রসঙ্গে ব্যবহার করা যাবে না।
ক্রিজিস্তফফ ক্রোসো

1
@ ডাম্যানিয়াক এটি ঠিকঠাক সংকলন করবে, তবে পরীক্ষাটি চালানোর সময় এটি অবৈধ ইউসঅফ ম্যাথার্স এক্সসেপশন (যা একটি রানটাইম এক্সেক্সশন) নিক্ষেপ করবে
সুপারল

277

এর @Mockপরিবর্তে অন্য একটি উপায় হ'ল পরিবর্তে টীকাটি ব্যবহার করা। সব ক্ষেত্রেই কাজ করে না, তবে অনেক বেশি যৌনদৃষ্টিতে দেখায় :)

এখানে একটি উদাহরণ:

@RunWith(MockitoJUnitRunner.class)
public class FooTests {

    @Mock
    public Foo<Bar> fooMock;

    @Test
    public void testFoo() {
        when(fooMock.getValue()).thenReturn(new Bar());
    }
}

MockitoJUnitRunnerসঙ্গে সটীক ক্ষেত্র সূচনা @Mock


3
এটি 1.9.5 এ অবচয় করা হয়েছে। :( আমার কাছে অনেক
পরিস্কার

12
টুইটগুলি তাহলে, অবমূল্যায়ন কী? (হ্যাঁ, org.mockito.MockitoAnnotations.Mock নিন্দা করা হয়েছে, কিন্তু এর পরিবর্তে আপনি যদি org.mockito.Mock ব্যবহার করা উচিত)
neu242

12
ভাল, এই আমার জন্য নিখুঁতভাবে কাজ। এটি কেবল "সেক্সিয়ার" নয়, এটি ব্যবহার না করে কোনও সতর্কতা এড়ানো হয় SuppressWarnings। সতর্কতাগুলি একটি কারণে উপস্থিত রয়েছে, সেগুলি দমন করার অভ্যাসে না থাকাই ভাল। ধন্যবাদ!
নিকোল

4
এর @Mockপরিবর্তে আমি ব্যবহার করতে পছন্দ করি না এমন একটি জিনিস রয়েছে mock(): নির্মাণের সময় ক্ষেত্রগুলি এখনও শূন্য থাকে, তাই আমি সেই সময়ে নির্ভরতা sertোকাতে পারি না এবং ক্ষেত্রগুলি চূড়ান্ত করতে পারি না। প্রাক্তনটি @Beforeঅবশ্যই একটি স্বীকৃত পদ্ধতি দ্বারা সমাধান করা যেতে পারে ।
রেডিগার স্কুল্জ

3
দীক্ষার জন্য কেবল মকিটোঅনোটেশন.ইনটমকস (এটি) কল করুন;
বোরজব

42

আপনি সর্বদা একটি মধ্যবর্তী শ্রেণি / ইন্টারফেস তৈরি করতে পারেন যা জেনেরিক ধরণের যেটি আপনি নির্দিষ্ট করতে চান তা সন্তুষ্ট করবে। উদাহরণস্বরূপ, ফু যদি একটি ইন্টারফেস হয়, আপনি নিজের পরীক্ষার শ্রেণিতে নিম্নলিখিত ইন্টারফেস তৈরি করতে পারেন।

private interface FooBar extends Foo<Bar>
{
}

Foo একটি চূড়ান্ত ক্লাস না এমন পরিস্থিতিতে আপনি নিম্নোক্ত কোড সহ ক্লাসটি প্রসারিত করতে এবং একই জিনিসটি করতে পারেন:

public class FooBar extends Foo<Bar>
{
}

তাহলে আপনি উপরের উদাহরণগুলির মধ্যে যে কোনও একটি নিম্নলিখিত কোড সহ গ্রাস করতে পারেন:

Foo<Bar> mockFoo = mock(FooBar.class);
when(mockFoo.getValue()).thenReturn(new Bar());

4
প্রদত্ত Fooএকটি ইন্টারফেস বা চূড়ান্ত নয় এমন শ্রেণি, এটি যুক্তিসঙ্গত মার্জিত সমাধান বলে মনে হয়। ধন্যবাদ।
টিম ক্লেমন্স

চূড়ান্তভাবে ক্লাসহীন ক্লাসগুলির উদাহরণ অন্তর্ভুক্ত করার জন্য আমি উত্তর আপডেট করেছি। আদর্শভাবে আপনি কোনও ইন্টারফেসের সাথে কোডিং করবেন তবে এটি সর্বদা ক্ষেত্রে হয় না। ভালো বল ধরা!
ডিসসিংটন

16

একটি পরীক্ষা ইউটিলিটি পদ্ধতি তৈরি করুন । যদি আপনার একাধিকবার প্রয়োজন হয় তবে বিশেষভাবে কার্যকর।

@Test
public void testMyTest() {
    // ...
    Foo<Bar> mockFooBar = mockFoo();
    when(mockFooBar.getValue).thenReturn(new Bar());

    Foo<Baz> mockFooBaz = mockFoo();
    when(mockFooBaz.getValue).thenReturn(new Baz());

    Foo<Qux> mockFooQux = mockFoo();
    when(mockFooQux.getValue).thenReturn(new Qux());
    // ...
}

@SuppressWarnings("unchecked") // still needed :( but just once :)
private <T> Foo<T> mockFoo() {
    return mock(Foo.class);
}

আপনি যে শ্রেণিতে উপহাস করতে চান তাতে কোনও সাধারণ ইউটিলিটি পদ্ধতি পাস করার জন্য আপনার উত্তর বাড়িয়ে দিতে পারে।
উইলিয়াম ডটন

1
@ উইলিয়ামডটন static <T> T genericMock(Class<? super T> classToMock) { return (T)mock(classToMock); }এটি এমনকি একটি দমন প্রয়োজন হয় না :) তবে সাবধান, Integer num = genericMock(Number.class)সংকলন, কিন্তু নিক্ষেপ ClassCastException। এটি কেবলমাত্র সর্বাধিক সাধারণ G<P> mock = mock(G.class)ক্ষেত্রে কার্যকর।
TWiStErRob

6

আমি সম্মত হই যে ক্লাসে বা পদ্ধতিতে সতর্কতাগুলিকে দমন করা উচিত নয় কারণ কোনও ব্যক্তি দুর্ঘটনাক্রমে চাপা সতর্কবাণীগুলিকে উপেক্ষা করতে পারে। তবে আইএমএইচএও এমন একটি সতর্কতা দমন করা একেবারে যুক্তিসঙ্গত যা কেবলমাত্র একক লাইনের কোডকে প্রভাবিত করে।

@SuppressWarnings("unchecked")
Foo<Bar> mockFoo = mock(Foo.class);

3

এখানে একটি আকর্ষণীয় কেস: পদ্ধতিটি জেনেরিক সংগ্রহ গ্রহণ করে এবং একই বেস ধরণের জেনেরিক সংগ্রহ প্রদান করে। উদাহরণ স্বরূপ:

Collection<? extends Assertion> map(Collection<? extends Assertion> assertions);

এই পদ্ধতিটি মকিতো যে কোনও সংকলন এবং ম্যাচ ম্যাচের সাথে এবং উত্তরের সংমিশ্রণে ঠাট্টা করা যায়।

when(mockedObject.map(anyCollectionOf(Assertion.class))).thenAnswer(
     new Answer<Collection<Assertion>>() {
         @Override
         public Collection<Assertion> answer(InvocationOnMock invocation) throws Throwable {
             return new ArrayList<Assertion>();
         }
     });
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.