অনেক ক্ষেত্রে আমার কিছু আচরণ সহ একটি বিদ্যমান বর্গ থাকতে পারে:
class Lion
{
public void Eat(Herbivore herbivore) { ... }
}
... এবং আমার একটি ইউনিট পরীক্ষা আছে ...
[TestMethod]
public void Lion_can_eat_herbivore()
{
var herbivore = buildHerbivoreForEating();
var test = BuildLionForTest();
test.Eat(herbivore);
Assert.IsEaten(herbivore);
}
এখন, আমার সিংহের সাথে পরিচয়মূলক আচরণ সহ একটি টাইগার শ্রেণি তৈরি করা দরকার:
class Tiger
{
public void Eat(Herbivore herbivore) { ... }
}
... এবং যেহেতু আমি একই আচরণ চাই, আমার একই পরীক্ষা চালানো দরকার, আমি এরকম কিছু করি:
interface IHerbivoreEater
{
void Eat(Herbivore herbivore);
}
... এবং আমি আমার পরীক্ষার রিফ্যাক্টর:
[TestMethod]
public void Lion_can_eat_herbivore()
{
IHerbivoreEater_can_eat_herbivore(BuildLionForTest);
}
public void IHerbivoreEater_can_eat_herbivore(Func<IHerbivoreEater> builder)
{
var herbivore = buildHerbivoreForEating();
var test = builder();
test.Eat(herbivore);
Assert.IsEaten(herbivore);
}
... এবং তারপরে আমি আমার নতুন Tigerক্লাসের জন্য আরও একটি পরীক্ষা যুক্ত করেছি :
[TestMethod]
public void Tiger_can_eat_herbivore()
{
IHerbivoreEater_can_eat_herbivore(BuildTigerForTest);
}
... এবং তারপরে আমি আমার Lionএবং Tigerক্লাসগুলি (সাধারণত উত্তরাধিকার সূত্রে, তবে কখনও কখনও রচনা দ্বারা) রিফ্যাক্টর করি :
class Lion : HerbivoreEater { }
class Tiger : HerbivoreEater { }
abstract class HerbivoreEater : IHerbivoreEater
{
public void Eat(Herbivore herbivore) { ... }
}
... এবং সব ঠিক আছে। তবে কার্যকারিতা যেহেতু এখন HerbivoreEaterক্লাসে রয়েছে তাই এখন মনে হচ্ছে প্রতিটি সাবক্লাসে এই প্রতিটি আচরণের জন্য পরীক্ষা করাতে কিছু ভুল আছে। তবুও এটি সাবক্লাসগুলি যা প্রকৃতপক্ষে গ্রাস করা হচ্ছে এবং এটি কেবলমাত্র বাস্তবায়নের বিশদ যা তারা ওভারল্যাপিং আচরণগুলি ভাগ করে নিতে পারে ( Lionsএবং Tigersউদাহরণস্বরূপ, এর সম্পূর্ণ ভিন্ন ব্যবহার থাকতে পারে)।
একই কোডটি একাধিকবার পরীক্ষা করা অযথা মনে হয়, তবে এমন কিছু ঘটনা রয়েছে যেখানে সাবক্লাস বেস ক্লাসের কার্যকারিতা ওভাররাইড করতে পারে এবং হ্যাঁ, এটি এলএসপি লঙ্ঘন করতে পারে তবে এর মুখোমুখি হতে দেয়, IHerbivoreEaterএটি কেবল একটি সুবিধাজনক পরীক্ষামূলক ইন্টারফেস - এটি শেষ ব্যবহারকারীর পক্ষে কোনও ব্যাপার না)। সুতরাং এই পরীক্ষাগুলির কিছু মূল্য আছে বলে আমি মনে করি।
এই পরিস্থিতিতে অন্যান্য লোকেরা কী করবে? আপনি কি কেবল নিজের পরীক্ষাটি বেস ক্লাসে সরিয়ে নিয়েছেন, বা প্রত্যাশিত আচরণের জন্য আপনি সমস্ত সাবক্লাসটি পরীক্ষা করেন?
সম্পাদনা :
@ পিডিআর থেকে প্রাপ্ত উত্তরের ভিত্তিতে আমি মনে করি আমাদের এটি বিবেচনা করা উচিত: এটি IHerbivoreEaterকেবল একটি পদ্ধতি স্বাক্ষরের চুক্তি; এটি আচরণ নির্দিষ্ট করে না। এই ক্ষেত্রে:
[TestMethod]
public void Tiger_eats_herbivore_haunches_first()
{
IHerbivoreEater_eats_herbivore_haunches_first(BuildTigerForTest);
}
[TestMethod]
public void Cheetah_eats_herbivore_haunches_first()
{
IHerbivoreEater_eats_herbivore_haunches_first(BuildCheetahForTest);
}
[TestMethod]
public void Lion_eats_herbivore_head_first()
{
IHerbivoreEater_eats_herbivore_head_first(BuildLionForTest);
}
Eatআচরণটি বেস শ্রেণিতে রাখেন তবে সমস্ত সাবক্লাসের একই Eatআচরণ প্রদর্শন করা উচিত । যাইহোক, আমি 2 অপেক্ষাকৃত অপ্রাসঙ্গিক শ্রেণীর কথা বলছি যা কোনও আচরণ ভাগ করে নেওয়ার জন্য ঘটে। উদাহরণস্বরূপ, আমরা বিবেচনা করতে পারি এবং এর Flyআচরণগুলি বিবেচনা করুন, আমরা একই ধরণের উড়ন্ত আচরণ প্রদর্শন করতে পারি তবে এগুলি একটি সাধারণ বেস শ্রেণি থেকে প্রাপ্ত হওয়া অগত্যা বোধগম্য নয়। BrickPerson
Animalক্লাস থাকা উচিত নয় যা রয়েছেEat? সমস্ত প্রাণী খায়, এবং সুতরাংTigerএবংLionশ্রেণি প্রাণী থেকে উত্তরাধিকারী হতে পারে।