এর অন্যতম কারণ হ'ল টেস্টেবলি। বলুন আপনার এই ক্লাস রয়েছে:
interface HttpLoader {
String load(String url);
}
interface StringOutput {
void print(String txt);
}
@Component
class MyBean {
@Autowired
MyBean(HttpLoader loader, StringOutput out) {
out.print(loader.load("http://stackoverflow.com"));
}
}
আপনি কিভাবে এই শিম পরীক্ষা করতে পারেন? যেমন:
class MyBeanTest {
public void creatingMyBean_writesStackoverflowPageToOutput() {
// setup
String stackOverflowHtml = "dummy";
StringBuilder result = new StringBuilder();
// execution
new MyBean(Collections.singletonMap("https://stackoverflow.com", stackOverflowHtml)::get, result::append);
// evaluation
assertEquals(result.toString(), stackOverflowHtml);
}
}
সহজ, তাই না?
আপনি এখনও স্প্রিংয়ের উপর নির্ভরশীল অবস্থায় (টীকাগুলির কারণে) কোনও কোড পরিবর্তন না করেই বসন্তের উপর নির্ভরতা সরিয়ে ফেলতে পারেন (কেবলমাত্র টীকা সংজ্ঞা) এবং পরীক্ষার বিকাশকারী কীভাবে বসন্ত কাজ করে সে সম্পর্কে কিছু জানতে হবে না (সম্ভবত তার যেভাবেই হওয়া উচিত, তবে এটি কোডটি পর্যালোচনা করতে এবং বসন্তের কাজ থেকে আলাদা করে পরীক্ষা করার অনুমতি দেয়)।
অ্যাপ্লিকেশন কনটেক্সটটি ব্যবহার করার সময় এখনও এটি করা সম্ভব। তবে আপনাকে বিদ্রূপ করা দরকার ApplicationContext
যা একটি বিশাল ইন্টারফেস। আপনার হয় একটি ডামি বাস্তবায়ন প্রয়োজন বা আপনি মকিতো এর মতো একটি মশকরা কাঠামো ব্যবহার করতে পারেন:
@Component
class MyBean {
@Autowired
MyBean(ApplicationContext context) {
HttpLoader loader = context.getBean(HttpLoader.class);
StringOutput out = context.getBean(StringOutput.class);
out.print(loader.load("http://stackoverflow.com"));
}
}
class MyBeanTest {
public void creatingMyBean_writesStackoverflowPageToOutput() {
// setup
String stackOverflowHtml = "dummy";
StringBuilder result = new StringBuilder();
ApplicationContext context = Mockito.mock(ApplicationContext.class);
Mockito.when(context.getBean(HttpLoader.class))
.thenReturn(Collections.singletonMap("https://stackoverflow.com", stackOverflowHtml)::get);
Mockito.when(context.getBean(StringOutput.class)).thenReturn(result::append);
// execution
new MyBean(context);
// evaluation
assertEquals(result.toString(), stackOverflowHtml);
}
}
এটি বেশ সম্ভাবনা, তবে আমি মনে করি বেশিরভাগ লোক সম্মত হবে যে প্রথম বিকল্পটি আরও মার্জিত এবং পরীক্ষাকে আরও সহজ করে তোলে।
সত্যিই সমস্যা হ'ল একমাত্র বিকল্পটি হ'ল:
@Component
class MyBean {
@Autowired
MyBean(StringOutput out) {
out.print(new HttpLoader().load("http://stackoverflow.com"));
}
}
এটি পরীক্ষার জন্য প্রচুর প্রচেষ্টা প্রয়োজন বা আপনার শিম প্রতিটি পরীক্ষার স্ট্যাকওভারফ্লোতে সংযোগ স্থাপনের চেষ্টা করতে চলেছে। এবং আপনার নেটওয়ার্ক ব্যর্থ হওয়ার সাথে সাথেই (বা অতিরিক্ত অ্যাক্সেস রেটের কারণে স্ট্যাকওভারফ্লোতে প্রশাসকরা আপনাকে অবরুদ্ধ করেছে) আপনার এলোমেলোভাবে ব্যর্থ পরীক্ষা হবে।
সুতরাং উপসংহার হিসাবে আমি বলব না যে ApplicationContext
সরাসরি ব্যবহার করা স্বয়ংক্রিয়ভাবে ভুল এবং কোনও মূল্যে এড়ানো উচিত। তবে যদি আরও ভাল বিকল্প থাকে (এবং বেশিরভাগ ক্ষেত্রে রয়েছে), তবে আরও ভাল বিকল্পগুলি ব্যবহার করুন।
new MyOtherClass()
? আমি @ অটোভায়ার্ড সম্পর্কে জানি, তবে আমি কেবল কখনও এটি মাঠে ব্যবহার করেছি এবং এটি ব্রেক হয়ে যায়new MyOtherClass()
..