() আমন্ত্রণটি কীভাবে মকিতো কাজ করে?


111

নিম্নলিখিত মকিতো বিবৃতি দেওয়া:

when(mock.method()).thenReturn(someValue);

মক.মোথোড () বিবৃতিটি কখন () এর সাথে ফেরতের মানটি পাস করবে তা প্রদত্ত মকিতো একটি উপহাসের জন্য প্রক্সিং কিছু তৈরি করার বিষয়ে কীভাবে যায়? আমি কল্পনা করি যে এটিতে কিছু সিজিবিব স্টাফ ব্যবহার করা হয়েছে তবে প্রযুক্তিগতভাবে এটি কীভাবে করা হয় তা জানতে আগ্রহী হবে।

উত্তর:


118

সংক্ষিপ্ত উত্তরটি হ'ল আপনার উদাহরণে, ফলাফলটি mock.method()একটি টাইপ-উপযুক্ত খালি মান হবে; মকিতো প্রক্সিং, পদ্ধতি ইন্টারসেপশন এবং এর একটি ভাগ করা দৃষ্টান্তের মাধ্যমে ইন্ডিয়ারেশন ব্যবহার করেMockingProgress ক্লাসের নির্ধারণ করার জন্য যে বা রিপ্লে করার জন্য বিদ্যমান স্টাব্বড আচরণের রিপ্লেয়ের পরিবর্তে মানগুলি ফেরতের মানের মাধ্যমে স্ট্যাবিংয়ের তথ্য পাস করার জন্য নয়? একটি উপহাস পদ্ধতি।

মকিটো কোডটি দেখে কয়েক মিনিটের মধ্যে একটি মিনি-অ্যানালাইসিস নীচে রয়েছে। দ্রষ্টব্য, এটি একটি মোটামুটি বর্ণনা - এখানে খেলতে প্রচুর বিবরণ রয়েছে। আমি আপনাকে গিথুবের উত্সটি পরীক্ষা করে দেখার পরামর্শ দিই নিজেই ।

প্রথমত, আপনি যখন ক্লাসের mockপদ্ধতিটি ব্যবহার করে কোনও শ্রেণিকে উপহাস করেন Mockito, মূলত যা ঘটে তা ঘটে:

  1. Mockito.mockorg.mockito.internal.MockitoCoreএকটি পরামিতি হিসাবে ডিফল্ট মক সেটিংস পাস করে .mock এ প্রতিনিধি ।
  2. MockitoCore.mockorg.mockito.internal.util.MockUtil.createMock এর প্রতিনিধি
  3. MockUtilবর্গ ব্যবহার ClassPathLoaderএর একটি দৃষ্টান্ত পেতে বর্গ MockMakerউপহাস তৈরি করতে ব্যবহার করতে। ডিফল্টরূপে, CgLibMockMaker শ্রেণি ব্যবহৃত হয়।
  4. CgLibMockMakerজেএমক থেকে ধার নেওয়া একটি শ্রেণি ব্যবহার ClassImposterizerকরে যা মক তৈরি করতে পরিচালনা করে। 'Mockito জাদু' ব্যবহার চাবি টুকরা হয় MethodInterceptormockito: উপহাস তৈরি করতে ব্যবহার করা MethodInterceptorFilter, এবং একটি দৃষ্টান্ত সহ MockHandler দৃষ্টান্ত, একটা চেন MockHandlerImpl । পদ্ধতি ইন্টারসেপ্টার মকহ্যান্ডলারআইম্পল উদাহরণটিতে অনুরোধগুলি প্রেরণ করে, যা মোকদ্দমাতে কোন পদ্ধতি প্রয়োগ করার সময় প্রয়োগ করা উচিত এমন ব্যবসায়িক যুক্তি প্রয়োগ করে (যেমন, উত্তরটি ইতিমধ্যে রেকর্ড করা হয়েছে কিনা তা সন্ধান করে, এই আহ্বানটি একটি নতুন স্টাবের প্রতিনিধিত্ব করে কিনা ইত্যাদি নির্ধারণ করে) etc. ডিফল্ট স্ট্যাটাসটি হ'ল যদি কোনও স্টাবটি চালিত হওয়ার পদ্ধতিটির জন্য ইতিমধ্যে নিবন্ধভুক্ত না হয় তবে একটি টাইপ-উপযুক্ত খালি মান ফিরে আসে is

এখন, আপনার উদাহরণে কোডটি দেখুন:

when(mock.method()).thenReturn(someValue)

এই কোডটি এখানে কার্যকর করা হবে এমন আদেশটি এখানে:

  1. mock.method()
  2. when(<result of step 1>)
  3. <result of step 2>.thenReturn

কী চলছে তা বোঝার মূল চাবিকাঠিটি হল যখন মোক নিয়ে পদ্ধতিটি আহ্বান করা হয় তখন কী ঘটে: পদ্ধতি ইন্টারসেপ্টারটি পদ্ধতিটি প্রার্থনার বিষয়ে তথ্য প্রেরণ করা হয় এবং এর MockHandlerউদাহরণগুলির শৃঙ্খলে প্রতিনিধি প্রেরণ করা হয় যা শেষ পর্যন্ত প্রেরণ করে MockHandlerImpl#handle। সময়কালে MockHandlerImpl#handle, মক হ্যান্ডলার একটি উদাহরণ তৈরি করে OngoingStubbingImplএবং এটিকে ভাগ করে দেওয়া হয়MockingProgress দৃষ্টান্তে ।

whenঅনুরোধের পরে যখন পদ্ধতিটি আহ্বান করা হয় method(), তখন এটি প্রতিনিধিত্ব করে MockitoCore.when, যা stub()একই বর্গের পদ্ধতিটিকে ডাকে । এই পদ্ধতিটি বিদ্রূপের অনুরোধটি MockingProgressযে ভাগ করা হয়েছে তাতে ভাগ করে নেওয়া দৃষ্টান্ত থেকে চলমান স্টাবকে আনপ্যাক করে method()এবং এটি ফেরত দেয়। তারপরে thenReturnমেথডকে ডাক দেওয়া হয় OngoingStubbing


1
বিস্তারিত প্রতিক্রিয়া জন্য ধন্যবাদ। আরেকটি প্রশ্ন - আপনি উল্লেখ করেছেন যে "যখন পদ্ধতিটি () পদ্ধতির () আহ্বানের পরে আহ্বান করা হয়" - তখন এটি কীভাবে জানতে পারে যে কখন () এর অনুরোধটি পদ্ধতিটির () আদান প্রদানের পরের আহবান (বা মোড়ানো)? আশা করি তা বোধগম্য হয়।
মার্চোস

@marchaos এটি জানেন না। সঙ্গে when(mock.method()).thenXyz(...)সিনট্যাক্স, mock.method()"রিপ্লে" মোডে মৃত্যুদন্ড কার্যকর করা, "stubbing" মোডে না। সাধারণত, এই সঞ্চালনের mock.method()কোনো প্রভাব নেই, তাই পরে thenXyz(...)( thenReturn, thenThrow, thenAnswer, ইত্যাদি) মৃত্যুদন্ড কার্যকর করা, এটা মোড "stubbing" মধ্যে যায় এবং তারপর যে পদ্ধতি কলের জন্য কাঙ্ক্ষিত ফলাফল রেকর্ড করে।
Rogério

1
রোজারিও, এটি আসলে তার থেকে খানিকটা সূক্ষ্ম - মকিতোর স্পষ্টভাবে স্ট্যাবিং এবং রিপ্লে মোড নেই। আমি আমার উত্তরটি পরে এডিট করব তাই এটি আরও পরিষ্কার।
পল মরি

সংক্ষেপে আমি সংক্ষেপে বলব, সিজিএলআইবি বা জাভাসিস্টের সাথে অন্য কোনও পদ্ধতির মধ্যে কোনও মেথড কলকে আটকানো সহজ, যাতে "যদি" অপারেটরকে বাধা দিতে হয়।
ইনফেলিগো

আমি এখনও আমার বিবরণটি এখানে ম্যাসেজ করিনি, তবে আমি এটির কথাও ভুলে যাইনি। অবগতির জন্য।
পল মরি

33

সংক্ষিপ্ত উত্তরটি হ'ল, পর্দার আড়ালে, মকিতো পদ্ধতি স্টাব বিল্ডিং স্টেপগুলির তথ্য সংরক্ষণের জন্য কিছু ধরণের গ্লোবাল ভেরিয়েবল / স্টোরেজ ব্যবহার করে (পদ্ধতির প্রার্থনা (), যখন (), তারপরে পুনরায় () আপনার উদাহরণে), যাতে শেষ পর্যন্ত এটি পারে কী পরমকে ডাকা হয় তখন কী ফিরিয়ে নেওয়া উচিত সে সম্পর্কে একটি মানচিত্র তৈরি করুন।

আমি এই নিবন্ধটি খুব সহায়ক বলে খুঁজে পেয়েছি: প্রক্সি ভিত্তিক মক ফ্রেমওয়ার্ক কীভাবে কাজ করে তা ব্যাখ্যা ( http://blog.rseiler.at/2014/06/explanation-how-proxy-based-mock.html )। লেখক একটি প্রদর্শনী মকিং ফ্রেমওয়ার্ক কার্যকর করেছেন, যা আমি এই লোকগুলির ফ্রেমওয়ার্কগুলি কীভাবে কাজ করে তা নির্ধারণ করতে চায় এমন লোকদের জন্য আমি খুব ভাল উত্স পেয়েছি।

আমার মতে এটি অ্যান্টি-প্যাটার্নের একটি সাধারণ ব্যবহার। সাধারণত যখন আমরা কোনও পদ্ধতি প্রয়োগ করি তখন আমাদের 'পার্শ্ব প্রতিক্রিয়া' এড়ানো উচিত, অর্থাত পদ্ধতিটির ইনপুট গ্রহণ করা উচিত এবং কিছু গণনা করা উচিত এবং ফলাফলটি ফিরিয়ে দেওয়া উচিত - এগুলি ছাড়া আর কিছুই পরিবর্তন হয়নি। তবে মকিতো কেবল সেই উদ্দেশ্যেটি লঙ্ঘন করেছে। এর পদ্ধতিগুলি ফলাফল ফিরিয়ে দেওয়ার পাশাপাশি একগুচ্ছ তথ্য সংরক্ষণ করে: মকিতো.নস্ট্রিং (), মকআইএনস্ট্যান্স.মোথডো (), যখন (), তখন রিটার্ন, তাদের সকলেরই বিশেষ 'পার্শ্ব প্রতিক্রিয়া' রয়েছে। এই কারণেই ফ্রেমওয়ার্কটি প্রথম নজরে ম্যাজিকের মতো দেখাচ্ছে - আমরা সাধারণত কোডটি লিখি না। যাইহোক, উপহাসের কাঠামোর ক্ষেত্রে, এই অ্যান্টি-প্যাটার্ন ডিজাইনটি একটি দুর্দান্ত নকশা, যেহেতু এটি খুব সাধারণ API এ নিয়ে যায়।


4
দুর্দান্ত লিঙ্ক। এর পেছনের প্রতিভাটি হ'ল: খুব সাধারণ এপিআই যা পুরো জিনিসটিকে খুব সুন্দর দেখাচ্ছে। আর একটি দুর্দান্ত সিদ্ধান্ত হ'ল যখন () পদ্ধতিটি জেনেরিকগুলি ব্যবহার করে যাতে তত্কালীন পুনরায় () পদ্ধতিটি টাইপ নিরাপদ থাকে।
ডেভিড টনহোফার

আমি এটি আরও ভাল উত্তর বিবেচনা। অন্য উত্তরের বিপরীতে, এটি কংক্রিট কোডের মাধ্যমে নিয়ন্ত্রণ প্রবাহের পরিবর্তে উপহাস প্রক্রিয়াটির ধারণাগুলি পরিষ্কারভাবে ব্যাখ্যা করে explains আমি সম্মত, দুর্দান্ত লিঙ্ক।
মিহকা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.