মকিতো: মক ব্যক্তিগত ক্ষেত্রের সূচনা


101

আমি কীভাবে একটি ক্ষেত্রের ভেরিয়েবলকে উপহাস করতে পারি যা ইনলাইনটি আরম্ভ করা হচ্ছে?

class Test {
    private Person person = new Person();
    ...
    public void testMethod() {
        person.someMethod();
        ...
    }
}

এখানে আমি person.someMethod()সেই Test.testMethod()পদ্ধতিটি পরীক্ষা করার সময় মশকরা করতে চাই যার জন্য আমাকে personভেরিয়েবলের আরম্ভকরণের উপহাস করতে হবে । কোন সুত্র?

সম্পাদনা: আমাকে ব্যক্তি শ্রেণি সংশোধন করার অনুমতি নেই।


4
এই লিঙ্কটি আপনার জন্য সহায়ক হতে পারে stackoverflow.com/questions/13645571/…
পোপিয়ে

4
আপনার কোডটি রিফ্যাক্টর করা উচিত যাতে আপনি একটি উপহাসে পাস করতে পারেন Person। বিকল্পগুলির মধ্যে এটি করার জন্য কোনও কনস্ট্রাক্টর যুক্ত করা বা সেটার পদ্ধতি যুক্ত করা অন্তর্ভুক্ত।
টিম বিগলাইসেন

উত্তর:


112

আপনাকে কিছু প্রতিবিম্ব বয়লার প্লেট কোড সংরক্ষণ করতে মকিতো একটি সহায়ক শ্রেণীর সাথে আসে:

import org.mockito.internal.util.reflection.Whitebox;

//...

@Mock
private Person mockedPerson;
private Test underTest;

// ...

@Test
public void testMethod() {
    Whitebox.setInternalState(underTest, "person", mockedPerson);
    // ...
}

আপডেট: দুর্ভাগ্যক্রমে মকিতো টিম মকিতো ২ তে ক্লাসটি সরিয়ে নেওয়ার সিদ্ধান্ত নিয়েছে তাই আপনি নিজের প্রতিচ্ছবি বয়লারপ্লেট কোডটি লিখে ফিরে এসেছেন, অন্য একটি লাইব্রেরি (যেমন অ্যাপাচি কমন্স ল্যাং ) ব্যবহার করুন, বা কেবল হোয়াইটবক্স ক্লাসটি চালিত করুন (এটি এমআইটি লাইসেন্সপ্রাপ্ত )।

আপডেট 2: জুনিট 5 তার নিজস্ব প্রতিচ্ছবি সমর্থন এবং এনোটেশনসপোর্ট ক্লাস নিয়ে আসে যা দরকারী হতে পারে এবং আপনাকে অন্য কোনও লাইব্রেরিতে টানতে বাঁচায়।


অন্যান্য কারণে আমি আমার টার্গেট অবজেক্টটি গুপ্তচর করছি এবং এই ক্ষেত্রে যখন আমার অবজেক্টটি গুপ্তচর হয়, আমি অভ্যন্তরীণ অবস্থাটি এভাবে সেট করতে পারি না।
অরুণ

কেন না? আমি গুপ্তচরদের সাথে এটি ব্যবহার করছি। একটি ব্যক্তি উদাহরণ তৈরি করুন। স্টিবিংয়ের যা কিছু দরকার তা স্টাব করুন, তারপরে এটি আপনার পরীক্ষার উদাহরণে সেট করুন।
রালফ

সতর্কতা: হোয়াইটবক্স internalপ্যাকেজে রয়েছে এবং মকিতো ২.6.২ এ আর কাজ করবে বলে মনে হয় না।
নোভা

আপনি ফিল্ডসেটর.সেটফিল্ড () ব্যবহার করতে পারেন। আমি নীচে তার জন্য উদাহরণ দিয়েছি।
রাজ কুমার

4
@ রাল্ফ কারণ জাভাতে একটি রেফারেন্স নাম পরিবর্তন করার ফলে সর্বদা সংকলনের ত্রুটি হওয়া উচিত।
জো কোডার

76

পার্টিতে বেশ দেরি হয়ে গেছে, তবে আমি এখানে আঘাত পেয়েছিলাম এবং এক বন্ধুর সাহায্য পেয়েছি। জিনিসটি পাওয়ারমক ব্যবহার করার ছিল না। এটি মকিতোর সর্বশেষতম সংস্করণটির সাথে কাজ করে।

মকিতো এই সঙ্গে আসে org.mockito.internal.util.reflection.FieldSetter

এটি মূলত যা করে তা হ'ল প্রতিফলন ব্যবহার করে ব্যক্তিগত ক্ষেত্রগুলি পরিবর্তন করতে সহায়তা করে।

আপনি এটি এভাবে ব্যবহার করেন:

@Mock
private Person mockedPerson;
private Test underTest;

// ...

@Test
public void testMethod() {
    FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person"), mockedPerson);
    // ...
    verify(mockedPerson).someMethod();
}

এইভাবে আপনি একটি মক অবজেক্টটি পাস করতে পারেন এবং তারপরে এটি যাচাই করতে পারেন।

এখানে রেফারেন্স দেওয়া আছে।


FieldSetterমকিতো ২.x এ আর উপলভ্য নয়।
রালফ

4
@ রাল্ফ আমি মকিতো-কোর-২.১৫.০ সংস্করণ ব্যবহার করছি। এটি সেখানে উপলব্ধ। static.javadoc.io/org.mockito/mockito-core/2.0.15-beta/org/… । তবুও বেটা।
রাজ কুমার

4
@ রাজকুমার Class#getDeclaredFieldএকক পরম গ্রহণ করে, তাই প্যারেনদের এইরকম দেখতে হবে FieldSetter.setField(underTest, underTest.getClass().getDeclaredField("person"), mockedPerson);। এইভাবেই আমি এটি ভুল পেয়েছি এবং এটি আপনার উদাহরণে এটি ঠিক করার জন্য ভাল ধারণা হতে পারে। জবাব দেওয়ার জন্য ধন্যবাদ
দাপেং লি

4
অভ্যন্তরীণ এপিআই ব্যবহার করা সেরা ধারণা নয়
ডেভিড

@ রাজকুমার নিস, তবে জিম্বো রজার যেমন উল্লেখ করেছেন: অভ্যন্তরীণ এপিআই ব্যবহার করা কি ভাল ধারণা? কেন এটি অভ্যন্তরীণ আকৃতির? এটি পরীক্ষার জন্য তাই দরকারী।
উইল মেন্টজেল

34

আপনি যদি স্প্রিং টেস্ট ব্যবহার করেন তবে org.springframework.test.util.ReflectionTestUtils ব্যবহার করে দেখুন

 ReflectionTestUtils.setField(testObject, "person", mockedPerson);

4
দুর্দান্ত! এই নিবন্ধটি লিংক করতে সাহায্য পারে এবং হয়ত নির্ভরতা তা থেকে এক চাহিদা রয়েছে: baeldung.com/spring-reflection-test-utils
উইলি Mentzel

build.gradle.kts:testImplementation("org.springframework:spring-test:5.1.2.RELEASE")
উইলি Mentzel

29

আমি এখানে পোস্ট করতে ভুলে গিয়েছিলাম যা এই সমস্যার সমাধান ইতিমধ্যে খুঁজে পেয়েছি।

@RunWith(PowerMockRunner.class)
@PrepareForTest({ Test.class })
public class SampleTest {

@Mock
Person person;

@Test
public void testPrintName() throws Exception {
    PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);
    Test test= new Test();
    test.testMethod();
    }
}

এই সমাধানের মূল বিষয়গুলি হ'ল:

  1. পাওয়ারমকরনারের সাথে আমার পরীক্ষার কেসগুলি চালাচ্ছি: @RunWith(PowerMockRunner.class)

  2. পাওয়ার ক্ষেত্রকে Test.classব্যক্তিগত ক্ষেত্রের কারসাজির জন্য প্রস্তুত করার নির্দেশ দিন :@PrepareForTest({ Test.class })

  3. এবং অবশেষে ব্যক্তি শ্রেণীর জন্য কনস্ট্রাক্টরকে উপহাস করুন:

    PowerMockito.mockStatic(Person.class); PowerMockito.whenNew(Person.class).withNoArguments().thenReturn(person);


9
আপনার ব্যাখ্যাটি mockStaticফাংশন সম্পর্কে কথা বলে , তবে এটি আপনার কোড উদাহরণে উপস্থাপিত হয় না। কোড উদাহরণে mockStaticকল করা উচিত, বা এটি নির্মাণকারীদের জন্য প্রয়োজনীয় নয়?
শাদোনিনজা

10

REST ক্লায়েন্ট মোককে ম্যাপার শুরু করতে নিম্নলিখিত কোড ব্যবহার করা যেতে পারে। mapperক্ষেত্র ব্যক্তিগত এবং ইউনিট পরীক্ষা সেট আপ করার সময় নির্ধারণ করা প্রয়োজন।

import org.mockito.internal.util.reflection.FieldSetter;

new FieldSetter(client, Client.class.getDeclaredField("mapper")).set(new Mapper());

5

আপনি যদি সমস্ত পরীক্ষার জন্য ভেরিয়েবলকে একই মান নির্ধারণ করতে চান তবে @ জর্দার গাইড ব্যবহার করে আপনি এটি সংজ্ঞায়িত করতে পারেন:

@Before
public void setClientMapper() throws NoSuchFieldException, SecurityException{
    FieldSetter.setField(client, client.getClass().getDeclaredField("mapper"), new Mapper());
}

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

উদাহরণস্বরূপ, আমি এটি ব্যবহার করি, উদাহরণস্বরূপ, ইউনিট পরীক্ষায় ঘুমের অপেক্ষা করার সময়টি পরিবর্তন করতে। বাস্তব উদাহরণগুলিতে আমি 10 সেকেন্ডের জন্য ঘুমাতে চাই তবে ইউনিট-টেস্টে আমি তাৎক্ষণিকভাবে সন্তুষ্ট। ইন্টিগ্রেশন পরীক্ষায় আপনার আসল মানটি পরীক্ষা করা উচিত।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.