ইউনিটটি এমন কোনও শ্রেণীর পরীক্ষা করে যা ইন্টার্নালগুলির পরীক্ষা না করে ডিআই ব্যবহার করে


12

আমার একটি ক্লাস রয়েছে যা ১ টি প্রধান শ্রেণিতে এবং ২ টি ছোট ক্লাসে রিফ্যাক্টর হয়। প্রধান ক্লাসগুলি ডেটাবেস ব্যবহার করে (আমার ক্লাসের অনেক কিছুই) এবং ইমেল প্রেরণ করে। সুতরাং প্রধান শ্রেণিতে একটি IPersonRepositoryএবং একটি IEmailRepositoryইনজেকশন রয়েছে যা তার পালা 2 টি ছোট ক্লাসে প্রেরণ করে।

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

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

অভ্যন্তরীণ সম্পর্কে পরীক্ষা না জেনে আমি কীভাবে এমন একটি শ্রেণীর পরীক্ষা করতে পারি যা নির্ভরতা ইঞ্জেকশন করেছে?

পটভূমি:

আমার অভিজ্ঞতার মতো প্রচুর পরীক্ষাগুলি সংগ্রহস্থলগুলির জন্য মক তৈরি করে এবং তারপরে মকগুলির জন্য সঠিক ডেটা সরবরাহ করে অথবা কার্যকর করার সময় যদি কোনও নির্দিষ্ট পদ্ধতি বলা হয়েছিল test যেভাবেই হোক, পরীক্ষাটি ইন্টার্নালগুলি সম্পর্কে জানে।

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


1
যত তাড়াতাড়ি আপনার প্রধান শ্রেণি কোনও IPersonRepositoryঅবজেক্টের প্রত্যাশা করবে , সেই ইন্টারফেস এবং এটি বর্ণিত সমস্ত পদ্ধতি আর কোনও "অভ্যন্তরীণ" নয়, সুতরাং এটি পরীক্ষার কোনও সমস্যা নয়। আপনার আসল প্রশ্নটি "জনসাধারণের মধ্যে খুব বেশি প্রকাশ না করে কীভাবে আমি ছোট ইউনিটগুলিতে ক্লাসগুলি সংশোধন করতে পারি" হওয়া উচিত। উত্তরটি হ'ল "সেই ইন্টারফেসগুলি সরু রাখুন" (উদাহরণস্বরূপ ইন্টারফেস বিভাজন নীতিটি আটকে রেখে)। এটি @ ডেভিডআর্নোর উত্তরের আইএমএইচও পয়েন্ট 2 (আমার ধারণা, অন্য উত্তরে আমার এটি পুনরাবৃত্তি করার প্রয়োজন নেই)।
ডক ব্রাউন 15

উত্তর:


7

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

আপনি ঠিক বলেছেন যে এটি "অভ্যন্তরীণ পরীক্ষা করবেন না" নীতি লঙ্ঘন করে এবং একটি সাধারণ বিষয় যা লোকে উপেক্ষা করে।

অভ্যন্তরীণ সম্পর্কে পরীক্ষা না জেনে আমি কীভাবে এমন একটি শ্রেণীর পরীক্ষা করতে পারি যা নির্ভরতা ইঞ্জেকশন করেছে?

এই লঙ্ঘনটি ঘটিয়ে কাজ করতে আপনি দুটি সমাধান গ্রহণ করতে পারেন:

1) একটি সম্পূর্ণ উপহাস সরবরাহ করুন IPersonRepository। আপনার বর্তমানে বর্ণিত পদ্ধতিটি পরীক্ষার অধীনে পদ্ধতির অভ্যন্তরীণ কর্মের জন্য মককে জুড়ে দেওয়া কেবলমাত্র যে পদ্ধতিগুলিতে কল করবে তা বিদ্রূপ করে। আপনি যদি সমস্ত পদ্ধতির জন্য মক সরবরাহ করেন IPersonRepositoryতবে আপনি সেই সংযোগটি সরিয়ে দিন। মককে প্রভাবিত না করে অভ্যন্তরীণ কাজগুলি পরিবর্তন করতে পারে, এইভাবে পরীক্ষাটি কম ভঙ্গুর করে তোলে।

এই পদ্ধতির ডিআই মেকানিজমকে সহজ রাখার সুবিধা রয়েছে তবে আপনার ইন্টারফেসটি যদি অনেক পদ্ধতি নির্ধারণ করে তবে এটি প্রচুর কাজ তৈরি করতে পারে।

2) ইনজেকশন করবেন না IPersonRepository, হয় GetSavingsByCustomerIdপদ্ধতিটি ইনজেক্ট করুন , না কোনও সঞ্চয় মূল্য ইনজেক্ট করুন। পুরো ইন্টারফেস বাস্তবায়নগুলি ইনজেকশনের সমস্যাটি হ'ল আপনি তখন দুটি ইনপ্রেকশন মিশ্রিত করে ("বলুন, জিজ্ঞাসা করবেন না") একটি "জিজ্ঞাসা করবেন না, বলুন না" সিস্টেমটি ইনজেকশন দিচ্ছেন। আপনি যদি একটি "খাঁটি ডিআই" পদ্ধতি গ্রহণ করেন তবে কোনও বস্তু দেওয়ার পরিবর্তে সেভিংসের মান চাইলে কলটি করার জন্য সঠিক পদ্ধতিটি (বলা) সরবরাহ করা উচিত (যা তারপরে কার্যকরভাবে পদ্ধতিটি কল করার জন্য জিজ্ঞাসা করতে হবে)।

এই পদ্ধতির সুবিধাটি হ'ল এটি মকগুলির প্রয়োজনীয়তা এড়িয়ে যায় (পরীক্ষার পদ্ধতিগুলির বাইরে যা আপনি পরীক্ষার অধীনে পদ্ধতিতে ইনজেক্ট করেন)। অসুবিধাটি হ'ল এটি পদ্ধতির পরিবর্তনের প্রয়োজনীয়তার প্রতিক্রিয়া হিসাবে পদ্ধতির স্বাক্ষরগুলিকে পরিবর্তনের কারণ হতে পারে।

উভয় পদ্ধতিরই মতামত এবং মতামত রয়েছে, তাই আপনার প্রয়োজনগুলির মধ্যে সবচেয়ে উপযুক্ত যেটি চয়ন করুন pick


1
আমি সত্যিই আইডিয়া নম্বর 2 পছন্দ করি আমি কেন জানি না যে আমি আগে এটি ভেবে দেখিনি। আমি বেশ কয়েক বছর ধরে আইআরপিওসিটরিগুলিতে নির্ভরতা তৈরি করে চলেছি এখনই নিজেকে জিজ্ঞাসা না করে কেন আমি পুরো আইরিপোসিটরির উপর নির্ভরতা তৈরি করেছি (যার মধ্যে বেশিরভাগ ক্ষেত্রে বেশিরভাগ পদ্ধতিতে স্বাক্ষর থাকবে) অন্যদিকে এটি কেবলমাত্র একটির উপর নির্ভরশীলতা রাখে বা 2 পদ্ধতি। সুতরাং IRepository ইনজেকশনের পরিবর্তে আমি আরও ভালভাবে ইনজেকশন করতে পারি বা (কেবলমাত্র) পদ্ধতির স্বাক্ষর দিয়ে পাস করতে পারি।
মিশেল

1

আমার পদ্ধতির হ'ল সংগ্রহস্থলগুলির 'মক' সংস্করণ তৈরি করা যা সাধারণ ফাইলগুলি থেকে প্রয়োজনীয় ডেটা ধারণ করে read

এর অর্থ স্বতন্ত্র পরীক্ষাটি মোকের সেটআপ সম্পর্কে 'জানেন না', যদিও সামগ্রিক পরীক্ষার প্রকল্পটি মককে উল্লেখ করবে এবং সেটআপ ফাইলগুলি থাকবে etc.

এটি মজাদার ফ্রেমওয়ার্কগুলির জন্য প্রয়োজনীয় জটিল মক অবজেক্ট সেটআপ এড়ায় এবং আপনাকে ইউআই টেস্টিং এবং এর মতো আপনার অ্যাপ্লিকেশনটির আসল দৃষ্টান্তগুলিতে 'মক' অবজেক্টগুলি ব্যবহার করতে দেয়।

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


2
এটি এখনও সেই পরিস্থিতির দিকে নিয়ে যায় যে পরীক্ষিত শ্রেণিটি ঠিক কী পদ্ধতিতে কাজ করছে তার জন্য আমি ডেটা সহ একটি উপহাস তৈরি করেছি। সুতরাং আমি এখনও এই সমস্যা আছে যে বাস্তবায়ন পরিবর্তন করা হলে, পরীক্ষা বিরতি হবে।
মিশেল

1
আমার দৃষ্টিভঙ্গি কেন আরও ভাল তা ব্যাখ্যা করার জন্য সম্পাদিত, যদিও এখনও আপনার মনে হওয়া দৃশ্যের জন্য আমি নিখুঁত নই
Ewan

1

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

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

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