यह निश्चित रूप से अपने सवाल का जवाब नहीं है, लेकिन अपनी ईमानदार राय में यह संबंधित है, यह उपयोगी और एक टिप्पणी के लिए बहुत बड़ा है।
मुझे अक्सर इस प्रश्न का सामना करना पड़ रहा है और मैं हमेशा "कन्स्ट्रक्टर निर्भरता इंजेक्शन" कर रहा हूं।
public class MyClassDoingSomething implements DoSomethig {
private final Service mainService;
@Inject
public MyClassDoingSomething(Service mainService) {
this.mainService = mainService;
}
}
सूचना कैसे निर्माता अब पैरामीटर प्राप्त करता है और इसे करने के लिए फ़ील्ड सेट करता है और है: इसका मतलब है कि मैं अब @Inject
के साथ मैदान व्याख्या द्वारा क्षेत्र इंजेक्शन है, लेकिन इतना की तरह निर्माता में निर्भरता पारित है @Inject
के साथ भी एनोटेटेड? मैं भी इन वर्गों (भी MyService
के लिए) एक इंटरफ़ेस को लागू करना चाहते - कई अन्य लाभ के बीच मुझे लगता है यह लिखने के लिए कटार मॉड्यूल आसान बना देता है:
@Module
public class DoSomethingModule {
@Provides @Singleton public RestService provideRestService() {
return new RestService();
}
@Provides @Singleton public MyPrinter provideMyPrinter() {
return new MyPrinter();
}
@Provides @Singleton public Service provideMyPrinter(MyService service) {
return service;
}
@Provides @Singleton public DoSomethig provideMyPrinter(MyClassDoingSomething something) {
return something;
}
}
(मतलब यह है कि MyService
औजार या Service
फैली)
अब तक ऐसा लगता है कि आप पहले ही जानते हैं कि डैगर स्वयं निर्भरता ग्राफ को समझने और आपके लिए सभी ऑब्जेक्ट्स बनाने में सक्षम है। तो वर्ग MyClassDoingSomething
कक्षा परीक्षण के बारे में क्या? मैं यहाँ भी डैगर का उपयोग नहीं करता हूं। मैं बस निर्भरता मैन्युअल रूप से प्रदान करता हूं:
public class MyClassDoingSomethingTest {
@Mock
Service service;
private MyClassDoingSomething something;
@Before
public void setUp() throws Exception {
MockitoAnnotations.init(this);
something = new MyClassDoingSomething(service);
}
// ...
}
जैसा कि आप देखते हैं, निर्भरता मैन्युअल रूप से निर्माता के माध्यम से पारित की जाती है।
स्पष्ट रूप से यह काम नहीं करता है अगर आप किसी ऐसे कोडिंग कर रहे हैं जिसमें आपके द्वारा कोई कन्स्ट्रक्टर नहीं है जिसे आपके द्वारा बुलाया जा सकता है। शास्त्रीय उदाहरण एंड्रॉइड गतिविधियों, टुकड़े या विचार हैं। इसे प्राप्त करने के तरीके हैं, लेकिन व्यक्तिगत रूप से मुझे अभी भी लगता है कि आप बिना किसी डैगर के इसे दूर कर सकते हैं। आप एक दृश्य एक क्षेत्र @Inject MyPresenter myPresenter
है कि परीक्षण इकाई कर रहे हैं, आम तौर पर इस क्षेत्र को पैकेज का उपयोग कर सकते है कि परीक्षण में ठीक काम करता है होगा:
public class MyViewTest {
@Mock MyPresenter presenter;
private MyView view;
@Before
public void setUp() throws Exception {
MockitoAnnotations.init(this);
view.myPresenter = presenter;
}
}
ध्यान दें कि यह केवल काम करता है अगर दोनों MyViewTest
और MyView
एक ही पैकेज में कर रहे हैं (जो अक्सर एंड्रॉइड परियोजनाओं में मामला है)।
दिन के अंत में आप अभी भी परीक्षण के लिए चाकू का उपयोग करना चाहते हैं, तो कभी "परीक्षण" मॉड्यूल और घटक है कि जैसे घटक में तरीकों की घोषणा के द्वारा इंजेक्षन कर सकते हैं बना सकते हैं:
@Inject
public interface MyTestComponent {
void inject(MyClassDoingSomething something);
}
मैं इस दृष्टिकोण को ठीक-एश ढूंढें, लेकिन मेरे विकास के वर्षों में मैं पहला दृष्टिकोण पसंद करता हूं। इसने Robolectric
के साथ समस्याओं की सूचना दी है कि build.gradle
फ़ाइल में कुछ सेटअप वास्तव में परीक्षण के लिए डैगर-कंपाइलर चलाने के लिए आवश्यक है ताकि कक्षाएं वास्तव में उत्पन्न हो जाएं।
ध्यान रखें कि _unit test_ में डैगर घटकों का उपयोग करना असामान्य है क्योंकि आपके टैग इंगित करते हैं; यूनिट परीक्षण के लिए, स्वयं रचनाकारों को कॉल करें और जितनी चाहें उतने मोक्स में गुजरें। _integration_, _system_, या _end-to-end_ परीक्षण के लिए, यह वास्तविक डैगर घटक का उपयोग करने के लिए और अधिक समझ में आता है, लेकिन फिर वास्तविक परीक्षण के लिए वास्तविक निर्भरताओं का उपयोग करने के लिए यह और अधिक समझ में आता है। –
धन्यवाद @ जेफबॉमन। कक्षा के नाम के कारण मैं आपको अपने इरादे से भ्रमित कर सकता हूं। मैंने MyClassDoTest को MyClassDoingSomething पर पुनर्नामित किया है। क्योंकि यह एक टेस्ट क्लास नहीं है, बल्कि एक वास्तविक वर्ग है। इसके लिए यूनिट टेस्ट एक अलग वर्ग होगा जो ऊपर दिए गए मेरे प्रश्न में परिभाषित नहीं है। घटना में मैं एक समारोह का परीक्षण कर रहा हूं i.e. MyPublicFunction MyClassDoing के भीतर कुछ जो मुख्य सेवा का उपयोग कर रहा है, मुझे एक mock mainService को MyClassDoingSomething में इंजेक्ट करने की आवश्यकता होगी। मुझे पता है कि कैसे इंजेक्ट करना है, लेकिन वास्तविक वस्तु के बजाय MyService इंजेक्ट का नकल पाने में सक्षम नहीं है। – Elye
हैलो। क्या आपको अंत में एक जवाब मिला? मैं एक ही मुद्दे से अटक गया: https://stackoverflow.com/questions/45166990/mock-injected-viewmodel –