আমি কীভাবে একটি ব্যক্তিগত ফাংশন বা এমন ক্লাসের পরীক্ষা করব যাতে ব্যক্তিগত পদ্ধতি, ক্ষেত্র বা অভ্যন্তরীণ ক্লাস রয়েছে?


2723

অভ্যন্তরীণ ব্যক্তিগত পদ্ধতি, ক্ষেত্র বা নেস্টেড ক্লাস রয়েছে এমন ক্লাসে আমি কীভাবে ইউনিট পরীক্ষা করব (xUnit ব্যবহার করে)? বা কোনও ফাংশন যা অভ্যন্তরীণ লিঙ্কেজ ( staticসি / সি ++ এ) দ্বারা ব্যক্তিগত করা হয়েছে বা কোনও ব্যক্তিগত ( বেনামে ) নামের জায়গায় রয়েছে?

কোনও পরীক্ষা চালাতে সক্ষম হতে কোনও পদ্ধতি বা ফাংশনের জন্য অ্যাক্সেস মডিফায়ার পরিবর্তন করা খারাপ বলে মনে হয়।


257
একটি ব্যক্তিগত পদ্ধতি পরীক্ষা করার সর্বোত্তম
সূর্য


383
আমি একমত নই একটি (সর্বজনীন) পদ্ধতি যা বোঝা দীর্ঘ বা কঠিন, তা পুনরায় সংশোধন করতে হবে। আপনি কেবল সর্বজনীন পদ্ধতির পরিবর্তে যে ছোট (ব্যক্তিগত) পদ্ধতিগুলি পান সেটি পরীক্ষা না করা বোকামি হবে।
মাইকেল পিফেল

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

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

উত্তর:


1638

হালনাগাদ:

প্রায় 10 বছর পরে কোনও ব্যক্তিগত পদ্ধতি, বা কোনও অ্যাক্সেস অযোগ্য সদস্যের পরীক্ষা করার সেরা উপায়টি ম্যানিফোল্ড ফ্রেমওয়ার্কের @Jailbreakমধ্য দিয়ে ।

@Jailbreak Foo foo = new Foo();
// Direct, *type-safe* access to *all* foo's members
foo.privateMethod(x, y, z);
foo.privateField = value;

এইভাবে আপনার কোডটি টাইপ-নিরাপদ এবং পাঠযোগ্য remains পরীক্ষার স্বার্থে কোনও নকশা আপোস, কোনও অতিরিক্ত পদ্ধতি এবং ক্ষেত্র নেই।

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

অভ্যন্তরীণভাবে আমরা সহায়তা / সেট privateএবং private staticভেরিয়েবলগুলির পাশাপাশি অনুরোধ privateএবং private staticপদ্ধতিগুলি ব্যবহার করতে সহায়তা করি। নিম্নলিখিত নিদর্শনগুলি আপনাকে ব্যক্তিগত পদ্ধতি এবং ক্ষেত্রগুলির সাথে সম্পর্কিত বেশ কিছু করতে দেয়। অবশ্যই, আপনি private static finalপ্রতিবিম্ব মাধ্যমে ভেরিয়েবল পরিবর্তন করতে পারবেন না ।

Method method = TargetClass.getDeclaredMethod(methodName, argClasses);
method.setAccessible(true);
return method.invoke(targetObject, argObjects);

এবং ক্ষেত্রগুলির জন্য:

Field field = TargetClass.getDeclaredField(fieldName);
field.setAccessible(true);
field.set(object, value);

দ্রষ্টব্য:
1. TargetClass.getDeclaredMethod(methodName, argClasses)আপনাকে privateপদ্ধতিগুলি সন্ধান করতে দেয় । একই জিনিস জন্য প্রযোজ্য getDeclaredField
২. setAccessible(true)বেসরকারীদের সাথে চারপাশে খেলতে হবে।


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

21
খুব দরকারী. এটি ব্যবহার করে মনে রাখা জরুরী যে টেস্টগুলি পোস্ট অবলোচনা চালানো হলে এটি খারাপভাবে ব্যর্থ হয়।
রিক মিনারিচ

20
উদাহরণস্বরূপ কোড আমাকে জন্য কাজ না করে, কিন্তু এই thigs পরিষ্কার করেছেন: java2s.com/Tutorial/Java/0125__Reflection/...
রব

35
সরাসরি প্রতিচ্ছবি ব্যবহারের চেয়ে পাওয়ারফুলের মতো কিছু লাইব্রেরি ব্যবহার করা আরও ভাল
মাইকেল পাইফেল

25
এই কারণেই টেস্ট ড্রাইভড ডিজাইন সহায়ক। আচরণটি যাচাই করার জন্য আপনাকে কী প্রকাশ করতে হবে তা নির্ধারণে এটি আপনাকে সহায়তা করে।
থরবজর্ন রাভন অ্যান্ডারসন

620

একটি ব্যক্তিগত পদ্ধতি পরীক্ষা করার সর্বোত্তম উপায় হ'ল অন্য পাবলিক পদ্ধতির মাধ্যমে। যদি এটি করা না যায় তবে নিম্নলিখিত শর্তগুলির মধ্যে একটি সত্য:

  1. ব্যক্তিগত পদ্ধতিটি ডেড কোড
  2. আপনি যে ক্লাসটি পরীক্ষা করছেন তার কাছাকাছি একটি ডিজাইনের গন্ধ রয়েছে
  3. আপনি যে পদ্ধতিটি পরীক্ষার চেষ্টা করছেন সেটি ব্যক্তিগত না হওয়া উচিত

6
তদুপরি, আমরা যাইহোক যাইহোক, কখনই 100% কোডের কভারেজের কাছাকাছি যাই না, সুতরাং ক্লায়েন্টরা সরাসরি যে পদ্ধতিগুলি সরাসরি ব্যবহার করবে সেগুলি সম্পর্কে কেন আপনার গুণমান পরীক্ষার সময়কে কেন কেন্দ্রীভূত করবেন না?
গ্রিঞ্চ

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

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

16
প্রায় সমস্ত ব্যক্তিগত পদ্ধতি সরাসরি পরীক্ষা করা উচিত নয় (রক্ষণাবেক্ষণ ব্যয় হ্রাস করতে)। ব্যতিক্রম: বৈজ্ঞানিক পদ্ধতিতে f (a (b (c (x), d (y))), a (e (x, z)), b (f (x, y, z), z)) এর মতো রূপ থাকতে পারে যেখানে ক, খ, সি, ডি, ই, এবং চ মারাত্মকভাবে জটিল ভাব প্রকাশ করছে তবে এই একক সূত্রের বাইরে অন্যথায় অকেজো। কিছু ফাংশন (এমডি 5 ভাবেন) বিপরীত করা কঠিন তাই প্যারামিটারগুলি চয়ন করা কঠিন (এনপি-হার্ড) হতে পারে যা আচরণের স্থানকে পুরোপুরি আবরণ করবে। A, b, c, d, e, f কে স্বতন্ত্রভাবে পরীক্ষা করা সহজ। তাদের সর্বজনীন বা প্যাকেজ-ব্যক্তিগত মিথ্যা করে তোলে যে তারা পুনরায় ব্যবহারযোগ্য। সমাধান: তাদের ব্যক্তিগত করুন, তবে তাদের পরীক্ষা করুন।
30:33

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

323

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

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

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

মনে রাখবেন যে আমি তাদের মস্তিষ্ক ব্যবহার না করে ক্লাস তৈরি করার পরামর্শ দিচ্ছি না! এখানে বক্তব্যটি হ'ল ইউনিট পরীক্ষার বাহিনীটি আপনাকে নতুন নতুন ক্লাসগুলি খুঁজে পেতে সহায়তা করার জন্য ব্যবহার করা।


24
প্রশ্ন ছিল কীভাবে ব্যক্তিগত পদ্ধতি পরীক্ষা করা যায়। আপনি বলেছেন যে আপনি তার জন্য নতুন ক্লাস করবেন (এবং আরও জটিলতা যুক্ত করুন) এবং নতুন ক্লাস তৈরি না করার পরামর্শ দেওয়ার পরে। সুতরাং কিভাবে ব্যক্তিগত পদ্ধতি পরীক্ষা?
ডেইনিয়াস

27
@ ডেইনিয়াস: আমি কেবলমাত্র নতুন ক্লাস তৈরি করার পরামর্শ দিচ্ছি না যাতে আপনি এই পদ্ধতিটি পরীক্ষা করতে পারেন। আমি পরামর্শ দিচ্ছি যে রাইটিং টেস্টগুলি আপনাকে আপনার নকশাটি উন্নত করতে সহায়তা করতে পারে: ভাল ডিজাইনগুলি পরীক্ষা করা সহজ।
জে বাজুজি 4'12

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

6
@ ড্যানিয়াস: একটি নতুন ক্লাস যুক্ত করা বেশিরভাগ ক্ষেত্রে জটিলতা হ্রাস করে। শুধু এটি পরিমাপ। কিছু ক্ষেত্রে টেস্টিবিলিটি ওওডির বিরুদ্ধে লড়াই করে। আধুনিক পদ্ধতি পরীক্ষার পক্ষে favor
অ্যালেক্সওয়েন

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

289

আমি জাভা এর জন্য অতীতে এই প্রতিচ্ছবি ব্যবহার করেছি এবং আমার মতে এটি একটি বড় ভুল ছিল।

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

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


76
এটি +1। আমার মতে এটি প্রশ্নের সেরা উত্তর। ব্যক্তিগত পদ্ধতি পরীক্ষা করে আপনি বাস্তবায়ন পরীক্ষা করছেন। এটি ইউনিট পরীক্ষার উদ্দেশ্যকে পরাস্ত করে, যা কোনও শ্রেণীর চুক্তির ইনপুট / আউটপুট পরীক্ষা করে। কোনও পরীক্ষার প্রয়োগের বিষয়ে নির্ভরশীলতার উপর কল করার পদ্ধতিগুলিকে উপহাস করার জন্য কেবল তার যথেষ্ট পরিমাণ জানতে হবে। বেশি কিছু না. যদি আপনি কোনও পরীক্ষা পরিবর্তন না করে আপনার বাস্তবায়ন পরিবর্তন করতে না পারেন - আপনার পরীক্ষার কৌশলটি দুর্বল হওয়ার সম্ভাবনা রয়েছে।
কলিন এম

10
@ কলিন এম এটি সত্যই যা জিজ্ঞাসা করছেন তা নয়;) তাকে এটি সিদ্ধান্ত নিতে দিন, আপনি প্রকল্পটি জানেন না।
অ্যারন মার্কাস

2
সত্যিই সত্য নয়। এটি ব্যবহারের জন্য পাবলিক পদ্ধতির মাধ্যমে ব্যক্তিগত পদ্ধতির একটি ছোট্ট অংশ পরীক্ষা করতে অনেক প্রচেষ্টা নিতে পারে। আপনার ব্যক্তিগত পদ্ধতিটি কল করে এমন লাইনে পৌঁছানোর আগে সর্বজনীন পদ্ধতির জন্য উল্লেখযোগ্য সেটআপের প্রয়োজন হতে পারে
ACV

1
আমি রাজী. আপনার পরীক্ষা করা উচিত, যদি চুক্তিটি পূর্ণ হয়। আপনার পরীক্ষা করা উচিত নয়, এটি কীভাবে হয়। যদি যোগাযোগটি 100% কোড কভারেজ (ব্যক্তিগত পদ্ধতিতে) না পৌঁছানোর পরে পূর্ণ হয় তবে তা মৃত বা অকেজো কোড হতে পারে।
wuppi

207

এই নিবন্ধ থেকে: JUnit এবং SuiteRunner (বিল ভেনার্স) এর সাথে ব্যক্তিগত পদ্ধতি পরীক্ষা করা , আপনার কাছে মূলত 4 টি বিকল্প রয়েছে:

  1. ব্যক্তিগত পদ্ধতি পরীক্ষা করবেন না।
  2. পদ্ধতিগুলি প্যাকেজ অ্যাক্সেস দিন।
  3. নেস্টেড টেস্ট ক্লাস ব্যবহার করুন।
  4. প্রতিবিম্ব ব্যবহার করুন।

@ জিমিটি।, "প্রোডাকশন কোড" কার জন্য তা নির্ভর করে। আমি ভিপিএন এর মধ্যে অবস্থিত অ্যাপ্লিকেশনগুলির জন্য উত্পাদিত কোড কল করব যার লক্ষ্য ব্যবহারকারীরা সায়সডমিনগুলি উত্পাদন কোড হতে পারে।
পেসারিয়ার

@ পেসারিয়ার মানে কী?
জিমি টি।

1
5 তম বিকল্প, যেমন উপরে উল্লিখিত পাবলিক পদ্ধতিটি পরীক্ষা করছে যা ব্যক্তিগত পদ্ধতিটিকে কল করে? সঠিক?
ব্যবহারকারী 2441441

1
@ লোরেঞ্জোরেট আমি এ নিয়ে কুস্তি করছি কারণ আমি এম্বেডড ডেভলপমেন্ট করছি এবং আমি চাই আমার সফ্টওয়্যারটি যতটা সম্ভব ছোট হোক। আকারের সীমাবদ্ধতা এবং পারফরম্যান্সই আমি ভাবতে পারি reason

আমি প্রতিবিম্বটি ব্যবহার করে পরীক্ষাটি সত্যিই পছন্দ করি: এখানে প্যাটার্ন পদ্ধতি পদ্ধতি = টার্গেটক্লাস.সেটক্ল্যারমেডথোড (মেথডনাম, আর্গক্লাস); method.setAccessible (সত্য); রিটার্ন মেথডিনোভোক (টার্গেটওজেক্ট, আরগোঅবজেক্টস);
Aguid

127

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


16
এটিই সেরা উত্তর আইএমও, বা সাধারণত যেমনটি বলা হয়, পরীক্ষার আচরণ, পদ্ধতি নয়। ইউনিট টেস্টিং উত্স কোড মেট্রিক্স, স্ট্যাটিক কোড বিশ্লেষণ সরঞ্জাম এবং কোড পর্যালোচনার জন্য প্রতিস্থাপন নয়। যদি ব্যক্তিগত পদ্ধতিগুলি এত জটিল হয় যে তাদের পৃথক পৃথক পরীক্ষাগুলির প্রয়োজন হয় তবে সম্ভবত এটির পুনঃসংশ্লিষ্ট হওয়া দরকার, এটিতে আরও পরীক্ষা নিক্ষেপ করা হয় না।
ড্যান হেইনেস

14
তাই প্রাইভেট পদ্ধতি লিখবেন না, মাত্র 10 টি ছোট ছোট ক্লাস তৈরি করবেন?
রেজার

1
না, এর মূল অর্থ এই যে আপনি ব্যক্তিগত পদ্ধতিগুলির অনুরোধ করে এমন পাবলিক পদ্ধতি ব্যবহার করে ব্যক্তিগত পদ্ধতিগুলির কার্যকারিতা পরীক্ষা করতে পারেন।
অক্ষত শারদা

66

আমি যেখানে একটি ব্যক্তিগত পদ্ধতি পরীক্ষা করতে চাই তার দুটি মাত্র উদাহরণ:

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

আমি কেবল "চুক্তি" পরীক্ষা করার ধারণাটি বুঝতে পারি। তবে আমি দেখতে পাচ্ছি না যে কেউ আসলে কোড টেস্টিংয়ের পক্ষে পরামর্শ করতে পারে না - আপনার মাইলেজটি বিভিন্ন রকম হতে পারে।

সুতরাং আমার ট্রেডঅফটিতে আমার নিরাপত্তা ও এসডিকে আপোষ না করে প্রতিচ্ছবিতে জুনিটকে জটিল করা জড়িত।


5
যদিও এটি পরীক্ষা করার জন্য আপনার কোনও পদ্ধতি সর্বজনীন করা উচিত privateনয়, এটি একমাত্র বিকল্প নয়। কোনও অ্যাক্সেস মডিফায়ার নয় package privateএবং এর অর্থ হল যে আপনি যতক্ষণ না আপনার ইউনিট পরীক্ষা একই প্যাকেজে বসবাস করেন ততক্ষণ আপনি এটি পরীক্ষা করতে পারবেন।
এনগ্রিন

1
আমি আপনার উত্তরটি সম্পর্কে মন্তব্য করছিলাম, বিশেষত 1 পয়েন্ট, ওপি নয়। কোনও পদ্ধতি ব্যক্তিগত করার দরকার নেই কারণ আপনি এটি সর্বজনীন হতে চান না।
ngreen

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

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

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

59

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


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

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

39

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

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

উদাহরণস্বরূপ, যদি পরীক্ষা করার মতো কোনও পদ্ধতি থাকে src/main/java/mypackage/MyClass.javaতবে আপনার পরীক্ষার কলটি ভিতরে রাখা উচিত src/test/java/mypackage/MyClassTest.java। এইভাবে, আপনি নিজের পরীক্ষার ক্লাসে পরীক্ষা পদ্ধতিতে অ্যাক্সেস পেয়েছেন।


1
আমি এটির সম্পর্কে জানতাম না, এটি হস্তক্ষেপ করছে, আমি এখনও মনে করি যে যদি আপনার এই ধরণের টিকা প্রয়োজন হয় তবে আপনার নকশার সমস্যা রয়েছে।
31:25

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

@ ফ্রজ জেরেমিক্রিগ - এর অর্থ কী?
মাস্টারজয়ে 2

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

34

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

আমি জাভা-র জন্য জুনিটেক্স.ইউটি.প্রাইভেটএ্যাকসেসর- প্যাকেজ ব্যবহার করি । ব্যক্তিগত পদ্ধতি এবং ব্যক্তিগত ক্ষেত্রে অ্যাক্সেসের জন্য প্রচুর সহায়ক ওয়ান-লাইনার।

import junitx.util.PrivateAccessor;

PrivateAccessor.setField(myObjectReference, "myCrucialButHardToReachPrivateField", myNewValue);
PrivateAccessor.invoke(myObjectReference, "privateMethodName", java.lang.Class[] parameterTypes, java.lang.Object[] args);

2
সমগ্র JUnit-অ্যাডঅনস (ডাউনলোডকৃত করতে ভুলবেন না sourceforge.net/projects/junit-addons ) প্যাকেজ, না উত্স ফোর্জ-সুপারিশকৃত প্রকল্প PrivateAccessor।
skia.heliou

2
এবং নিশ্চিত হয়ে নিন যে, আপনি যখন Classএই পদ্ধতিগুলিতে আপনার প্রথম প্যারামিটার হিসাবে ব্যবহার করছেন তখন আপনি কেবল staticসদস্যদের অ্যাক্সেস করছেন ।
skia.heliou

31

ইন স্প্রিং ফ্রেমওয়ার্ক আপনি ব্যক্তিগত পদ্ধতি এই পদ্ধতি ব্যবহার করে পরীক্ষা করুন:

ReflectionTestUtils.invokeMethod()

উদাহরণ স্বরূপ:

ReflectionTestUtils.invokeMethod(TestClazz, "createTest", "input data");

এখন পর্যন্ত সবচেয়ে পরিষ্কার এবং সবচেয়ে সংক্ষিপ্ত সমাধান, তবে কেবল আপনি যদি বসন্ত ব্যবহার করছেন।
ডেনিস নিকোলেনকো

28

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

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

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

সুবিধাদি:

  • একটি সূক্ষ্ম গ্রানুলারিটি পরীক্ষা করতে পারেন

অসুবিধা:

  • টেস্ট কোডটি অবশ্যই সোর্স কোডের মতো একই ফাইলে থাকতে হবে যা বজায় রাখা আরও কঠিন হতে পারে
  • একইভাবে .class আউটপুট ফাইলগুলির সাথে, তাদের অবশ্যই সোর্স কোডে ঘোষিত একই প্যাকেজের মধ্যে থাকতে হবে

যাইহোক, যদি ক্রমাগত পরীক্ষার জন্য এই পদ্ধতির প্রয়োজন হয় তবে এটি একটি সংকেত হতে পারে যে ব্যক্তিগত পদ্ধতিগুলি উত্তোলন করা উচিত, যা প্রচলিত, পাবলিক উপায়ে পরীক্ষা করা যেতে পারে।

এটি কীভাবে কাজ করবে তার একটি বিভ্রান্ত উদাহরণ:

// Import statements and package declarations

public class ClassToTest
{
    private int decrement(int toDecrement) {
        toDecrement--;
        return toDecrement;
    }

    // Constructor and the rest of the class

    public static class StaticInnerTest extends TestCase
    {
        public StaticInnerTest(){
            super();
        }

        public void testDecrement(){
            int number = 10;
            ClassToTest toTest= new ClassToTest();
            int decremented = toTest.decrement(number);
            assertEquals(9, decremented);
        }

        public static void main(String[] args) {
            junit.textui.TestRunner.run(StaticInnerTest.class);
        }
    }
}

অভ্যন্তরীণ ক্লাসটি সংকলিত হবে ClassToTest$StaticInnerTest

আরও দেখুন: জাভা টিপ 106: মজা এবং লাভের জন্য স্থির অভ্যন্তরীণ ক্লাস


26

অন্যরা যেমন বলেছে ... সরাসরি ব্যক্তিগত পদ্ধতি পরীক্ষা করবেন না। এখানে কয়েকটি চিন্তা:

  1. সমস্ত পদ্ধতি ছোট এবং কেন্দ্রীভূত রাখুন (যা পরীক্ষা করা সহজ, কী ভুল তা খুঁজে বের করার সহজ)
  2. কোড কভারেজ সরঞ্জাম ব্যবহার করুন। আমি কোবার্টুরা পছন্দ করি ( ওহে শুভ দিন, দেখে মনে হচ্ছে একটি নতুন সংস্করণ বেরিয়েছে!)

ইউনিট পরীক্ষায় কোড কভারেজ চালান। যদি আপনি দেখতে পান যে পদ্ধতিগুলি পুরোপুরি পরীক্ষিত নয় তবে কভারেজটি বাড়ানোর জন্য পরীক্ষাগুলিতে যুক্ত করুন। 100% কোড কভারেজের জন্য লক্ষ্য, তবে বুঝতে পারেন যে আপনি সম্ভবত এটি পাবেন না।


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

আমি এমন ক্লাস দেখেছি যেখানে একমাত্র সর্বজনীন পদ্ধতি প্রধান [], এবং তারা জিইউআই পপআপ করে এবং বিশ্বব্যাপী ডাটাবেস এবং বেশ কয়েকটি ওয়েব সার্ভারকে সংযুক্ত করে। "পরোক্ষভাবে পরীক্ষা করবেন না" বলা সহজ ...
অড্রিয়াস মেসকাউকাস

26

ব্যক্তিগত পদ্ধতিগুলি জনসাধারণ দ্বারা গ্রাস করা হয়। অন্যথায়, তারা ডেড কোড। এজন্যই আপনি সর্বজনীন পদ্ধতিটি পরীক্ষা করেন, পাবলিক পদ্ধতির প্রত্যাশিত ফলাফল এবং ততক্ষণে এটি ব্যবহার করা ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করে as

ব্যক্তিগত পদ্ধতি পরীক্ষা করে সর্বজনীন পদ্ধতিতে আপনার ইউনিট পরীক্ষা চালানোর আগে ডিবাগিংয়ের মাধ্যমে পরীক্ষা করা উচিত।

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

আমি ব্যক্তিগতভাবে টিডিডি ব্যবহার করে ক্লাস তৈরি করা ভাল বলে বিশ্বাস করি; পাবলিক মেথড স্টাব তৈরি করা, তারপরে ইউনিট টেস্ট তৈরি করা সমস্ত সংক্ষিপ্ত বিবরণ আগে থেকেই সংজ্ঞায়িত করা হয়, সুতরাং আপনার কোড করার আগে পদ্ধতির প্রত্যাশিত ফলাফলটি নির্ধারিত হয়। এইভাবে, আপনি ইউনিট পরীক্ষার দৃser় ফলাফলগুলি মাপসই করার ভুল পথে নামবেন না। আপনার ক্লাসটি তখন শক্তিশালী এবং আপনার সমস্ত ইউনিট পরীক্ষা পাস করার সময় প্রয়োজনীয়তা পূরণ করে।


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

24

যদি স্প্রিং ব্যবহার করা হয় তবে রিফ্লেকশন টেস্ট Utils কিছু হ্যান্ডি সরঞ্জাম সরবরাহ করে যা এখানে সর্বনিম্ন প্রচেষ্টা সহ সহায়তা করে। উদাহরণস্বরূপ, একটি অনাকাঙ্ক্ষিত পাবলিক সেটার যুক্ত করতে বাধ্য না করে কোনও প্রাইভেট সদস্যকে উপহাস স্থাপন:

ReflectionTestUtils.setField(theClass, "theUnsettableField", theMockObject);

24

আপনি যদি বিদ্যমান কোডটি পরীক্ষা করার চেষ্টা করছেন যা আপনি অনিচ্ছুক বা পরিবর্তন করতে অক্ষম, প্রতিচ্ছবি একটি ভাল পছন্দ।

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

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


19

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

সুতরাং ব্যক্তিগত পদ্ধতি পরীক্ষা করবেন না।


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

1
কোড পরিবর্তন হলে ইউনিট পরীক্ষার পরিবর্তন হওয়া উচিত বলে সম্মত হন না। যদি আপনাকে ক্লাসের বিদ্যমান কার্যকারিতা পরিবর্তন না করে কোনও ক্লাসে কার্যকারিতা যুক্ত করার আদেশ দেওয়া হয় তবে আপনার কোড পরিবর্তন করার পরেও বিদ্যমান ইউনিট পরীক্ষাগুলি পাস হওয়া উচিত। পিটার যেমন উল্লেখ করেছেন, ইউনিট টেস্টগুলির ইন্টারফেসটি পরীক্ষা করা উচিত, এটি অভ্যন্তরীণভাবে কীভাবে করা হয় তা নয়। পরীক্ষায় চালিত বিকাশ ইউনিটের পরীক্ষাগুলি কোডটি লেখার আগে তৈরি করা হয়, শ্রেণীর ইন্টারফেসের উপর দৃষ্টি নিবদ্ধ করা, অভ্যন্তরীণভাবে কীভাবে এটি সমাধান করা হয় তা নয় not
হ্যারাল্ড কোপলস

16

JUnit.org এফএকিউ পৃষ্ঠা থেকে উত্তর :

তবে আপনি যদি অবশ্যই ...

আপনি JDK 1.3 ব্যবহার বা উচ্চতর হয়, আপনি সাহায্যে প্রবেশাধিকার নিয়ন্ত্রণ প্রক্রিয়া পরাভূত করে প্রতিফলন ব্যবহার করতে পারেন PrivilegedAccessor । কীভাবে এটি ব্যবহার করবেন সে সম্পর্কে বিশদ জানতে এই নিবন্ধটি পড়ুন

আপনি যদি জেডিকে ১.6 বা ততোধিক উচ্চতর ব্যবহার করছেন এবং আপনি @ টেস্টের সাহায্যে আপনার পরীক্ষাগুলি টিকাদান দিচ্ছেন, আপনি নিজের পরীক্ষার পদ্ধতিগুলিতে প্রতিচ্ছবি ইনজেক্ট করতে Dp4j ব্যবহার করতে পারেন । কীভাবে এটি ব্যবহার করবেন সে সম্পর্কে বিশদ জানতে এই পরীক্ষার স্ক্রিপ্টটি দেখুন

পিএস আমি Dp4j এর প্রধান অবদানকারী , আপনার যদি সাহায্যের দরকার হয় তবে আমাকে জিজ্ঞাসা করুন । :)


16

আপনি যদি কোনও লিগ্যাসি অ্যাপ্লিকেশনটির ব্যক্তিগত পদ্ধতিগুলি পরীক্ষা করতে চান যেখানে আপনি কোডটি পরিবর্তন করতে পারবেন না, জাভার জন্য একটি বিকল্প হ'ল jMockit , যা শ্রেণিতে ব্যক্তিগত থাকার পরেও আপনাকে কোনও বস্তুতে মক তৈরি করতে অনুমতি দেবে।


4
Jmockit লাইব্রেরির অংশ হিসাবে, আপনি ডিনক্যাপসুলেশন ক্লাসে অ্যাক্সেস পেয়েছেন যা ব্যক্তিগত পদ্ধতি পরীক্ষা করা সহজ করে তোলে: Deencapsulation.invoke(instance, "privateMethod", param1, param2);
ডোমেনিক ডি

আমি এই পদ্ধতির সব সময় ব্যবহার করি। অত্যন্ত সহায়ক
MedicineMan

14

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


14

আপনি JUnit ব্যবহার করছেন, জুনিট অ্যাডন তাকান । এটি জাভা সুরক্ষা মডেল উপেক্ষা এবং ব্যক্তিগত পদ্ধতি এবং বৈশিষ্ট্য অ্যাক্সেস করার ক্ষমতা আছে।


13

আমি আপনাকে কিছুটা আপনার কোডটি রিফ্যাক্ট করার পরামর্শ দেব। আপনার কোডটি পরীক্ষা করার জন্য আপনাকে যখন প্রতিবিম্ব বা অন্যান্য ধরণের স্টাফ ব্যবহার করার কথা ভাবতে শুরু করে তখন আপনার কোডের সাথে কিছু ভুল হচ্ছে।

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

public class ClassToTest {

    private final String first = "first";
    private final List<String> second = new ArrayList<>();
    ...
}

আমি এটি ব্যবহার করতাম:

public class ClassToTest {

    private final String first;
    private final List<String> second;

    public ClassToTest() {
        this("first", new ArrayList<>());
    }

    public ClassToTest(final String first, final List<String> second) {
        this.first = first;
        this.second = second;
    }
    ...
}

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

এখন বেসরকারী পদ্ধতি সম্পর্কে। আমার ব্যক্তিগত অভিজ্ঞতায় যখন আপনাকে পরীক্ষার জন্য কোনও ব্যক্তিগত পদ্ধতিতে স্টাড করতে হয়, তখন সেই পদ্ধতিটির সেই শ্রেণিতে কিছুই করার থাকে না। একটি সাধারণ প্যাটার্ন, সেক্ষেত্রে এটি একটি ইন্টারফেসের মধ্যে আবৃত করা হবে, Callableএবং তারপরে আপনি সেই ইন্টারফেসটি কনস্ট্রাক্টরেও পাস করবেন (সেই একাধিক কনস্ট্রাক্টর ট্রিক সহ):

public ClassToTest() {
    this(...);
}

public ClassToTest(final Callable<T> privateMethodLogic) {
    this.privateMethodLogic = privateMethodLogic;
}

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

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

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


1
ClassToTest(Callable)ইনজেকশনের সাথে দ্বিমত পোষণ করুন । এটি ClassToTestআরও জটিল করে তোলে । সহজবোধ্য রাখো. এছাড়াও, এরপরে অন্য কারও কাছে ClassToTestএমন কিছু বলার প্রয়োজন ClassToTestযা মনিব হওয়া উচিত। ইনজেকশন যুক্তির জন্য একটি জায়গা আছে, তবে এটি এটি নয়। আপনি ক্লাস বজায় রাখা আরও কঠিন করেছেন, সহজ নয় not
লুডুভিজক

এছাড়াও, যদি আপনার পরীক্ষার পদ্ধতিটি আরও বেশি সমস্যা সৃষ্টি করতে পারে এমন জটিলতায় সমস্যা Xনা বাড়িয়ে দেয় X... এবং সেইজন্য অতিরিক্ত পরীক্ষার প্রয়োজন হয় ... যা যদি আপনি এমনভাবে প্রয়োগ করেন যা আরও সমস্যার কারণ হতে পারে .. (এটি কোনও অসীম লুপ নয়; প্রতিটি পুনরাবৃত্তি সম্ভবত
আগেরটির

2
আপনি ব্যাখ্যা করতে পারেন কেন এটি বর্গ ClassToTestবজায় রাখা কঠিন করে তুলবে ? আসলে এটি আপনার অ্যাপ্লিকেশনটি বজায় রাখা আরও সহজ করে তোলে, আপনার প্রয়োজনীয় প্রতিটি ভিন্ন মান firstএবং 'দ্বিতীয়' ভেরিয়েবলের জন্য নতুন শ্রেণি তৈরি করার কী পরামর্শ দেন ?
GROX13

1
পরীক্ষার পদ্ধতি জটিলতা বাড়ায় না। এটি কেবল আপনার ক্লাস যা খারাপ লেখা হয়েছে, এত খারাপভাবে যে এটি পরীক্ষা করা যায় না।
GROX13

বজায় রাখা আরও শক্ত কারণ ক্লাসটি আরও জটিল। class A{ A(){} f(){} }তুলনায় সহজ class A { Logic f; A(logic_f) } class B { g() { new A( logic_f) } }। যদি এটি সত্য না হয় এবং যদি এটি সত্য হয় যে কোনও শ্রেণীর যুক্তি হিসাবে কনস্ট্রাক্টর আর্গুমেন্ট সরবরাহ করা সহজতর ছিল তবে আমরা সমস্ত যুক্তিকে কনস্ট্রাক্টর আর্গুমেন্ট হিসাবে পাস করব। আমি ঠিক দেখতে পাই না আপনি কীভাবে দাবি করতে পারেন class B{ g() { new A( you_dont_know_your_own_logic_but_I_do ) } }তা বজায় রাখা আরও সহজ করে তোলে। এমন কেস রয়েছে যেখানে
ইনজেকশনটি

12

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

এবং তারপরে একটি সুরক্ষিত পদ্ধতিটি কেবল একই প্যাকেজের মধ্যেই ক্লাস সংজ্ঞায়িত করা যেতে পারে। সুতরাং, একটি লক্ষ্য শ্রেণীর একটি সুরক্ষিত পদ্ধতি পরীক্ষা করার অর্থ হ'ল লক্ষ্য পরীক্ষার মতো একই প্যাকেজে আপনার পরীক্ষা শ্রেণিটি সংজ্ঞায়িত করা আমাদের প্রয়োজন।

যদি উপরের সমস্তটি আপনার প্রয়োজন অনুসারে না খায় তবে ব্যক্তিগত পদ্ধতিতে অ্যাক্সেস করার জন্য প্রতিবিম্বিত উপায়টি ব্যবহার করুন


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

1
আসলে জাভাতে কোনও "বন্ধুত্বপূর্ণ" নেই, শব্দটি "প্যাকেজ" এবং এটি একটি ব্যক্তিগত / পাবলিক / সুরক্ষিত সংশোধকটির অভাব দ্বারা নির্দেশিত। আমি কেবল এই উত্তরটি সংশোধন করতে পারব তবে ইতিমধ্যে একটি ভাল উত্তর রয়েছে যা ইতিমধ্যে এটি বলেছে - সুতরাং আমি কেবল এটি মুছে ফেলার প্রস্তাব দিই।
বিল কে

"আমি এই উত্তরটি পুরোপুরি ভুল বলেছি" all যতক্ষণ না আমি একেবারে শেষ বাক্যটিতে পৌঁছেছি, যা বাকী উত্তরের সাথে বিরোধী। শেষ বাক্যটি প্রথম হওয়া উচিত ছিল।
লুডুভিজক

11

উপরোক্ত অনেকে পরামর্শ দিয়েছেন, একটি ভাল উপায় হ'ল এটি আপনার পাবলিক ইন্টারফেসের মাধ্যমে পরীক্ষা করা।

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


আপনার পরোক্ষভাবে পরীক্ষা করা উচিত নয়! কেবল কভারেজের মাধ্যমে স্পর্শ নয়; প্রত্যাশিত ফলাফল বিতরণ করা হয় যে পরীক্ষা!
অ্যালেক্সওয়েন

11

ব্যক্তিগত ক্ষেত্রগুলি পরীক্ষা করার জন্য আমার জেনেরিক ফাংশনটি এখানে:

protected <F> F getPrivateField(String fieldName, Object obj)
    throws NoSuchFieldException, IllegalAccessException {
    Field field =
        obj.getClass().getDeclaredField(fieldName);

    field.setAccessible(true);
    return (F)field.get(obj);
}

10

উদাহরণস্বরূপ নীচে দেখুন;

নিম্নলিখিত আমদানি বিবৃতি যোগ করা উচিত:

import org.powermock.reflect.Whitebox;

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

Whitebox.invokeMethod(obj, "privateMethod", "param1");

10

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

আপনি যদি ব্যক্তিগত পদ্ধতি বা ক্ষেত্র বা নির্মাতাদের সাথে কিছু কোড পেয়ে থাকেন তবে আপনি বাউন্ডবক্স ব্যবহার করতে পারেন । এটি আপনি যা খুঁজছেন ঠিক তা করে। এখানে নীচে এমন একটি পরীক্ষার উদাহরণ দেওয়া আছে যা এটি পরীক্ষা করতে অ্যান্ড্রয়েড ক্রিয়াকলাপের দুটি ব্যক্তিগত ক্ষেত্র অ্যাক্সেস করে:

@UiThreadTest
public void testCompute() {

    // Given
    boundBoxOfMainActivity = new BoundBoxOfMainActivity(getActivity());

    // When
    boundBoxOfMainActivity.boundBox_getButtonMain().performClick();

    // Then
    assertEquals("42", boundBoxOfMainActivity.boundBox_getTextViewMain().getText());
}

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

এটি কিছু উত্তরাধিকার কোড পরীক্ষা করার জন্য আদর্শ। সাবধানে এটি ব্যবহার করুন। ;)

https://github.com/stephanenicolas/boundbox


1
এটি চেষ্টা করে দেখুন, বাউন্ডবক্স একটি সাধারণ এবং মার্জিত এবং সমাধান!
ফরহাস

9

প্রথমত, আমি এই প্রশ্নটি ছুঁড়ে দেব: আপনার ব্যক্তিগত সদস্যদের বিচ্ছিন্ন পরীক্ষা কেন দরকার? তারা কি সেই জটিল, জনসাধারণের ত্বকে পৃথক করে টেস্টিংয়ের মতো জটিল আচরণ সরবরাহ করে? এটি ইউনিট টেস্টিং, 'লাইন অফ-কোড' পরীক্ষা নয়। ছোট জিনিস ঘামবেন না।

যদি তারা এত বড় হয় যে এত বড় যে এই ব্যক্তিগত সদস্যরা প্রতিটি জটিলতার জন্য একটি 'ইউনিট' বড় হন - এই শ্রেণীর বাইরে এই জাতীয় ব্যক্তিগত সদস্যদের রিফ্যাক্টারে বিবেচনা করুন।

যদি রিফ্যাক্টরিং অনুপযুক্ত বা অনিবার্য হয় তবে ইউনিট পরীক্ষার সময় আপনি কি এই ব্যক্তিগত সদস্য ফাংশন / সদস্য শ্রেণিতে অ্যাক্সেস প্রতিস্থাপনের জন্য কৌশল বিন্যাসটি ব্যবহার করতে পারেন? ইউনিট পরীক্ষার অধীনে, কৌশলটি অতিরিক্ত বৈধতা সরবরাহ করবে, তবে মুক্তির ক্ষেত্রে এটি সহজ পাসস্ট্র্রু হবে।


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

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

8

আমি সম্প্রতি এই সমস্যাটি পেয়েছি এবং একটি ছোট সরঞ্জাম লিখেছি, বলা হয় পিকলক যা স্পষ্টভাবে জাভা প্রতিবিম্ব এপিআই ব্যবহার করার সমস্যাগুলি এড়ায় , দুটি উদাহরণ:

কল করার পদ্ধতিগুলি, যেমন private void method(String s) - জাভা প্রতিবিম্ব দ্বারা

Method method = targetClass.getDeclaredMethod("method", String.class);
method.setAccessible(true);
return method.invoke(targetObject, "mystring");

কল করার পদ্ধতিগুলি, যেমন private void method(String s) - পিকলক দ্বারা

interface Accessible {
  void method(String s);
}

...
Accessible a = ObjectAccess.unlock(targetObject).features(Accessible.class);
a.method("mystring");

ক্ষেত্র স্থাপন, যেমন private BigInteger amount; - জাভা প্রতিবিম্ব দ্বারা

Field field = targetClass.getDeclaredField("amount");
field.setAccessible(true);
field.set(object, BigInteger.valueOf(42));

ক্ষেত্র স্থাপন, উদাহরণস্বরূপ private BigInteger amount;- পিকলক দ্বারা

interface Accessible {
  void setAmount(BigInteger amount);
}

...
Accessible a = ObjectAccess.unlock(targetObject).features(Accessible.class);
a.setAmount(BigInteger.valueOf(42));

7

পাওয়ারমোকিটো এটির জন্য তৈরি করা হয়েছে। মাভেন নির্ভরতা ব্যবহার করুন

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-mockito-release-full</artifactId>
    <version>1.6.4</version>
</dependency>

তাহলে আপনি করতে পারেন

import org.powermock.reflect.Whitebox;
...
MyClass sut = new MyClass();
SomeType rval = Whitebox.invokeMethod(sut, "myPrivateMethod", params, moreParams);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.