Mockito matchers স্ট্যাটিক পদ্ধতি এবং সেই পদ্ধতি, যা কল হয় আর্গুমেন্ট জন্য দাঁড়ানো কল সময় when
এবং verify
।
হ্যামক্রেস্ট ম্যাথারস (আর্কাইভ সংস্করণ) (বা হ্যামক্রেস্ট-স্টাইলের ম্যাথারস) রাষ্ট্রবিহীন, সাধারণ-উদ্দেশ্য বস্তুর উদাহরণস্বরূপ যে Matcher<T>
কোনও পদ্ধতি কার্যকর করে এবং প্রকাশ করে matches(T)
যে বস্তু ম্যাচারের মানদণ্ডের সাথে মেলে যদি সত্য ফিরে আসে returns এগুলি পার্শ্ব প্রতিক্রিয়া মুক্ত থাকার উদ্দেশ্যে করা হয় এবং সাধারণত নীচের মত জোর হিসাবে ব্যবহৃত হয়।
/* Mockito */ verify(foo).setPowerLevel(gt(9000));
/* Hamcrest */ assertThat(foo.getPowerLevel(), is(greaterThan(9000)));
মকিতো ম্যাথারস উপস্থিত রয়েছে, হামক্রস্ট-স্টাইলের ম্যাথার থেকে পৃথক, যাতে মিলের অভিব্যক্তিগুলির বিবরণগুলি সরাসরি পদ্ধতি আমন্ত্রণের সাথে ফিট করে : মকিতো ম্যাচারগুলি ফিরে আসে T
যেখানে হ্যামরেস্ট ম্যাচার পদ্ধতিগুলি ম্যাচার অবজেক্টগুলি (টাইপের Matcher<T>
) প্রত্যাবর্তন করে ।
Mockito matchers যেমন স্ট্যাটিক পদ্ধতিগুলির মাধ্যমে প্রার্থনা করছে eq
, any
, gt
, এবং startsWith
উপর org.mockito.Matchers
এবং org.mockito.AdditionalMatchers
। এছাড়াও অ্যাডাপ্টারগুলি রয়েছে, যা মকিতো সংস্করণগুলিতে পরিবর্তিত হয়েছে:
- মকিতো ১.x এর জন্য
Matchers
কিছু কল রয়েছে (যেমন intThat
বা argThat
) হ'ল মকিতো ম্যাথাররা যা হ্যামক্রস্ট ম্যাথারগুলিকে প্যারামিটার হিসাবে সরাসরি গ্রহণ করে। ArgumentMatcher<T>
প্রসারিত org.hamcrest.Matcher<T>
, যা অভ্যন্তরীণ হামক্রস্টের উপস্থাপনায় ব্যবহৃত হয়েছিল এবং এটি কোনও প্রকার মকিতো ম্যাচারের পরিবর্তে হামক্রস্ট ম্যাচারের বেস ক্লাস ছিল ।
- মকিতো ২.০+ এর জন্য, মকিতোর আর হ্যামকারেস্টের উপর সরাসরি নির্ভরতা নেই।
Matchers
রিং phrased intThat
বা argThat
মোড়ানো ArgumentMatcher<T>
যে বস্তু আর বাস্তবায়ন org.hamcrest.Matcher<T>
কিন্তু অনুরূপ উপায়ে ব্যবহার করা হয়। হামক্রস্ট অ্যাডাপ্টার যেমন argThat
এবং intThat
এখনও পাওয়া যায়, তবে MockitoHamcrest
পরিবর্তে চলে গেছে ।
ম্যাচাররা হ্যামক্রেস্ট বা কেবল হ্যামক্রস্ট-স্টাইলই হোক না কেন, সেগুলি এ জাতীয়ভাবে মানিয়ে নেওয়া যায়:
/* Mockito matcher intThat adapting Hamcrest-style matcher is(greaterThan(...)) */
verify(foo).setPowerLevel(intThat(is(greaterThan(9000))));
উপরের বিবৃতিতে: foo.setPowerLevel
একটি পদ্ধতি যা গ্রহণ করে int
। is(greaterThan(9000))
একটি প্রদান করে Matcher<Integer>
, যা setPowerLevel
আর্গুমেন্ট হিসাবে কাজ করবে না । intThat
মকিতো ম্যাচার মোড়কে দেয় যে হামক্রস্ট-স্টাইলের ম্যাচার এবং একটি ফেরত দেয় int
যাতে এটি যুক্তি হিসাবে উপস্থিত হতে পারে; মকিতো ম্যাচাররা gt(9000)
উদাহরণস্বরূপ কোডের প্রথম লাইনের মতো সেই সম্পূর্ণ এক্সপ্রেশনটিকে একটি একক কলে মুড়িয়ে দেবে।
ম্যাথাররা কী করে / ফেরত দেয়
when(foo.quux(3, 5)).thenReturn(true);
যুক্তি ম্যাথারগুলি ব্যবহার না করার সময়, মকিতো আপনার যুক্তির মানগুলি রেকর্ড করে এবং তাদের equals
পদ্ধতিগুলির সাথে তাদের তুলনা করে ।
when(foo.quux(eq(3), eq(5))).thenReturn(true); // same as above
when(foo.quux(anyInt(), gt(5))).thenReturn(true); // this one's different
আপনি যখন ম্যাচারকে এর মতো any
বা gt
(এর চেয়ে বড়) কল করেন, মকিতো এমন ম্যাচারকারী বস্তু সঞ্চয় করে যা মকিতো সেই সমতা পরীক্ষাটি এড়িয়ে যায় এবং আপনার পছন্দের ম্যাচটি প্রয়োগ করে। argumentCaptor.capture()
এটির ক্ষেত্রে একটি ম্যাচার সংরক্ষণ করে যা পরে তদন্তের পরিবর্তে তার যুক্তিটি সংরক্ষণ করে।
ম্যাচার্স শূন্য, খালি সংগ্রহ বা ডামি মানগুলি ফিরিয়ে দেয় null
। Mockito জন্য 0 মত একটি নিরাপদ, উপযুক্ত ডামি মান ফেরত পাঠাতে, চেষ্টা করে anyInt()
বা any(Integer.class)
অথবা একটি খালি List<String>
জন্য anyListOf(String.class)
। টাইপ ইরেজরের কারণে, যদিও, মকিতোতে কোনও মান ফেরত দেওয়ার জন্য টাইপের তথ্যের অভাব রয়েছে বা এর null
জন্য any()
বা argThat(...)
, যা একটি null
আদিম মান "অটো-আনবক্স" করার চেষ্টা করলে নলপয়েন্টারএক্সসেপশন ঘটাতে পারে।
ম্যাচাররা প্যারামিটারের মানগুলি পছন্দ করে eq
এবং gt
নেয়; আদর্শভাবে, স্টাবিং / যাচাইকরণ শুরু হওয়ার আগে এই মানগুলি গণনা করা উচিত। বিদ্রূপের মাঝামাঝি সময়ে অন্য কলটি কল করা স্টাবের সাথে হস্তক্ষেপ করতে পারে।
ম্যাচের পদ্ধতিগুলি রিটার্ন মান হিসাবে ব্যবহার করা যায় না; উদাহরণস্বরূপ বাক্যাংশ thenReturn(anyInt())
বা thenReturn(any(Foo.class))
মকিতোতে কোনও উপায় নেই । স্টিবিং কলগুলিতে কোন উদাহরণটি ফিরে আসবে তা অবশ্যই মকিতোকে জানতে হবে এবং আপনার জন্য নির্বিচারে রিটার্ন মান চয়ন করবে না।
বাস্তবায়ন বিশদ
ম্যাচারস আর্গুমেন্টম্যাচারস্টোরেজ নামে একটি ক্লাসে থাকা একটি স্ট্যাকে (হামক্রস্ট-স্টাইলের অবজেক্ট ম্যাচচার হিসাবে) সংরক্ষণ করা হয় । MockitoCore এবং Matchers প্রতিটি নিজের একটি ThreadSafeMockingProgress উদাহরণস্বরূপ, যা স্ট্যাটিক্যালি একটি ThreadLocal হোল্ডিং MockingProgress দৃষ্টান্ত রয়েছে। এটি এই মকিংপ্রোগ্রেস ইমপল যা একটি কংক্রিট আর্গুমেন্টম্যাচারস্টোরেজআইপল ধারণ করে । ফলস্বরূপ, মোক এবং ম্যাচার অবস্থা স্থিতিশীল তবে মকিতো এবং ম্যাচার্স শ্রেণীর মধ্যে ধারাবাহিকভাবে থ্রেড-স্কোপড।
সর্বাধিক মিলকারীর কল শুধুমাত্র মত matchers জন্য একটি ব্যতিক্রম সঙ্গে, এই স্ট্যাকের যোগ and
, or
এবংnot
। এটি পুরোপুরি জাওয়ার মূল্যায়ন আদেশের সাথে (এবং এর উপর নির্ভর করে) যা কোনও পদ্ধতিতে বলার আগে বাম থেকে ডান যুক্তির মূল্যায়ন করে:
when(foo.quux(anyInt(), and(gt(10), lt(20)))).thenReturn(true);
[6] [5] [1] [4] [2] [3]
এটা হবে:
anyInt()
স্ট্যাক যোগ করুন ।
gt(10)
স্ট্যাক যোগ করুন ।
lt(20)
স্ট্যাক যোগ করুন ।
- সরান
gt(10)
এবং lt(20)
যোগ করুন and(gt(10), lt(20))
।
- কল করুন
foo.quux(0, 0)
, যা (অন্যথায় স্টাব না করা হলে) ডিফল্ট মানটি দেয় false
। অভ্যন্তরীণভাবে মকিতো quux(int, int)
সবচেয়ে সাম্প্রতিক কল হিসাবে চিহ্নিত করেছে ।
- কল
when(false)
, যা তার যুক্তিটি বাতিল করে এবং quux(int, int)
5 টিতে চিহ্নিত স্টাব পদ্ধতিটি প্রস্তুত করে: কেবলমাত্র দুটি বৈধ রাষ্ট্র স্ট্যাকের দৈর্ঘ্য 0 (সমতা) বা 2 (ম্যাথার) সহ এবং স্ট্যাকের দুটি পদক্ষেপ রয়েছে (পদক্ষেপ 1 এবং 4), সুতরাং মকিতো any()
তার প্রথম তর্ক এবং and(gt(10), lt(20))
দ্বিতীয় তর্কটির জন্য ম্যাচারের সাথে পদ্ধতিটি স্টাব করে এবং স্ট্যাকটি সাফ করে।
এটি কয়েকটি বিধি প্রদর্শন করে:
মকিতো quux(anyInt(), 0)
এবং এর মধ্যে পার্থক্য বলতে পারে না quux(0, anyInt())
। তারা উভয় quux(0, 0)
স্ট্যাকের উপর একটি আন্ত ম্যাচারের সাথে কল করার মতো দেখায় । ফলস্বরূপ, আপনি যদি একটি ম্যাচার ব্যবহার করেন তবে আপনাকে সমস্ত যুক্তি মেলাতে হবে।
কল অর্ডার কেবল গুরুত্বপূর্ণ নয়, এটি এটিকে সমস্ত কাজ করে । ভেরিয়েবলগুলিতে ম্যাথারগুলি সরানো সাধারণত কাজ করে না, কারণ এটি সাধারণত কল ক্রম পরিবর্তন করে। পদ্ধতিগুলিতে ম্যাথারগুলি এক্সট্র্যাক্ট করা দুর্দান্ত কাজ করে।
int between10And20 = and(gt(10), lt(20));
/* BAD */ when(foo.quux(anyInt(), between10And20)).thenReturn(true);
// Mockito sees the stack as the opposite: and(gt(10), lt(20)), anyInt().
public static int anyIntBetween10And20() { return and(gt(10), lt(20)); }
/* OK */ when(foo.quux(anyInt(), anyIntBetween10And20())).thenReturn(true);
// The helper method calls the matcher methods in the right order.
স্ট্যাকটি প্রায়শই যথেষ্ট পরিবর্তিত হয় যে মকিতো খুব সাবধানতার সাথে এটি পুলিশ করতে পারে না। এটি যখন আপনি মকিতো বা একটি উপহাসের সাথে ইন্টারঅ্যাক্ট করেন তখন এটি স্ট্যাকটি পরীক্ষা করতে পারে এবং অবিলম্বে ব্যবহৃত হয় বা দুর্ঘটনাক্রমে পরিত্যক্ত হয় কিনা তা জেনেও ম্যাচারদের গ্রহণ করতে হবে। তাত্ত্বিকভাবে, স্ট্যাকটি কল করার when
বা তার বাইরে সর্বদা খালি থাকা উচিত verify
, তবে মকিতো স্বয়ংক্রিয়ভাবে তা পরীক্ষা করতে পারে না। আপনি নিজে দিয়ে চেক করতে পারেন Mockito.validateMockitoUsage()
।
কলটিতে when
, মকিতো আসলে সেই পদ্ধতিটিকে প্রশ্নবিদ্ধভাবে কল করে, যা যদি আপনি ব্যতিক্রম ছুঁড়ে দেওয়ার জন্য পদ্ধতিটি স্টাড করে থাকেন (বা শূন্যের বা অ-নাল মানগুলির প্রয়োজন হয়) তবে এটি ব্যতিক্রম করবে।
doReturn
এবং doAnswer
(ইত্যাদি) না না প্রকৃত পদ্ধতি ডাকা এবং প্রায়ই একটি দরকারী বিকল্প হয়।
আপনি stubbing মাঝখানে একটি উপহাস পদ্ধতি বলা হত (যেমন একটি জন্য একটি উত্তর নিরূপণ করা eq
মিলকারীর), Mockito বিরুদ্ধে স্ট্যাক দৈর্ঘ্য চেক করবে যে পরিবর্তে কল, এবং সম্ভবত ব্যর্থ হয়।
আপনি যদি চূড়ান্ত পদ্ধতিতে স্টাবিং / যাচাইয়ের মতো খারাপ কিছু করার চেষ্টা করেন তবে মকিতো আসল পদ্ধতিটি কল করবে এবং স্ট্যাকের উপরে অতিরিক্ত ম্যাচারও রেখে যাবে । final
পদ্ধতি কল একটি ব্যতিক্রম নিক্ষেপ নাও করতে পারে, কিন্তু আপনি এমন একটি পেতে পারেন InvalidUseOfMatchersException বিপথগামী matchers একটি উপহাস সঙ্গে যখন আপনি পরবর্তি ইন্টারঅ্যাক্ট থেকে।
সাধারন সমস্যা
অবৈধ ইউসঅফ ম্যাথার্স এক্সসেপশন :
যদি আপনি মোটেই ম্যাচার ব্যবহার করেন এবং আপনি যে কোনও when
বা verify
কলটির বাইরে কোনও ম্যাচার ব্যবহার করেন নি তা প্রতিটি যুক্তিতে ঠিক একটি ম্যাথার কল রয়েছে কিনা তা পরীক্ষা করে দেখুন । ম্যাচারদের কখনই স্টাবড রিটার্ন মান বা ক্ষেত্র / ভেরিয়েবল হিসাবে ব্যবহার করা উচিত নয়।
ম্যাচারের যুক্তি সরবরাহ করার অংশ হিসাবে আপনি কোন উপহাসকে কল করছেন না তা পরীক্ষা করুন।
আপনি কোনও ম্যাচারের সাথে চূড়ান্ত পদ্ধতিটি স্তম্ভিত / যাচাই করার চেষ্টা করছেন না তা পরীক্ষা করুন। স্ট্যাকের উপর ম্যাচার রেখে যাওয়ার এক দুর্দান্ত উপায় এবং যদি আপনার চূড়ান্ত পদ্ধতিটি ব্যতিক্রম না ছড়িয়ে দেয় তবে আপনি কেবল যে পদ্ধতিটি উপহাস করছেন তা চূড়ান্ত হওয়ার বিষয়টি আপনি কেবলমাত্র বুঝতে পারবেন।
আদিম আর্গুমেন্টের সাথে নালপয়েন্টারএক্সেপশন: 0 টি (Integer) any()
শূন্য করার সময় শূন্য any(Integer.class)
দেয়; NullPointerException
আপনি যদি int
একটি পূর্ণসংখ্যার পরিবর্তে এর চেয়ে প্রত্যাশা করছেন তবে এটির কারণ হতে পারে । যাই হোক না কেন, পছন্দ করুন anyInt()
, যা শূন্য ফিরে আসবে এবং অটো-বক্সিং পদক্ষেপও এড়িয়ে যাবে।
নালপয়েন্টারএক্সেপশন বা অন্যান্য ব্যতিক্রম: কল করার জন্য when(foo.bar(any())).thenReturn(baz)
আসলে কল হবে foo.bar(null)
, যা নাল যুক্তি পাওয়ার সময় আপনি কোনও ব্যতিক্রম ছুঁড়ে মারতে পারেন ub স্যুইচ করা doReturn(baz).when(foo).bar(any())
ছেড়ে যাওয়া stubbed আচরণ ।
সাধারণ সমস্যা সমাধান
মকিটোজেউইনিটরুনার ব্যবহার করুন , বা validateMockitoUsage
আপনার tearDown
বা @After
পদ্ধতিতে স্পষ্টভাবে কল করুন (যা রানার স্বয়ংক্রিয়ভাবে আপনার জন্য করবে)। আপনি ম্যাচারদের অপব্যবহার করেছেন কিনা তা এটি নির্ধারণে সহায়তা করবে।
ডিবাগিংয়ের উদ্দেশ্যে, validateMockitoUsage
আপনার কোডটিতে সরাসরি কলগুলি যুক্ত করুন । আপনার যদি স্ট্যাকের কিছু থাকে তবে এটি ফেলে দেবে, যা খারাপ লক্ষণের একটি ভাল সতর্কতা।