मैं एक माइक्रोनॉट क्लास का परीक्षण कर रहा हूं जिसमें एक बीन इंजेक्ट किया गया है। अपने परीक्षण में मैं इसे ओवरराइड करने के लिए एक @MockBean
वर्ग प्रदान करता हूं। हालांकि, ऐसा लगता है कि माइक्रोनॉट अभी भी वास्तविक निर्भरता को इंजेक्ट करता है।
@MicronautTest
public class ClassUnderTestTest {
@Inject ClassUnderTest classUnderTest;
@Test
public void test() {
}
@MockBean
Dependency dependency() {
return mock(Dependency.class);
}
}
मैंने Github पर एक न्यूनतम रेप्रो अपलोड किया है: https://github.com/crummy/micronaut-test-dependencies . वास्तविक निर्भरता एक अपवाद फेंकता है, और परीक्षण भी करता है। मुझे अपने @MockBean
के कारण ऐसा होने की उम्मीद नहीं थी।
अगर मैं एनोटेशन को @MockBean(Dependency.class)
में बदलता हूं तो मुझे यह त्रुटि मिलती है: Message: No bean of type [di.failure.example.Dependency] exists
। यह मेरे लिए और भी अधिक भ्रमित करने वाला लगता है - अब यह मेरी वास्तविक या मेरी नकली निर्भरता का समाधान नहीं करता है?
1 उत्तर
यदि आपकी निर्भरता ClassUnderTest
में इंटरफ़ेस द्वारा दर्शायी जाती है, तो @MockBean
एनोटेशन के साथ नकली बीन इंजेक्ट करना काम करता है। मान लें कि Dependency
एक सरल इंटरफ़ेस है जैसे:
package di.failure.example;
public interface Dependency {
void run();
}
आपका आवेदन DependencyImpl
नामक इस इंटरफ़ेस के लिए कार्यान्वयन प्रदान कर सकता है:
package di.failure.example;
import javax.inject.Singleton;
@Singleton
public class DependencyImpl implements Dependency {
@Override
public void run() {
throw new RuntimeException("I don't want this to load!");
}
}
अब, परीक्षण के उद्देश्य से आप एक नकली को परिभाषित कर सकते हैं जो DependencyImpl
को प्रतिस्थापित करता है:
package di.failure.example;
import io.micronaut.test.annotation.MicronautTest;
import io.micronaut.test.annotation.MockBean;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import static org.mockito.Mockito.mock;
@MicronautTest
public class ClassUnderTestTest {
@Inject
ClassUnderTest classUnderTest;
@Test
public void test() {
classUnderTest.run();
}
@MockBean(DependencyImpl.class)
public Dependency dependency() {
return mock(Dependency.class);
}
}
यह परीक्षण निष्पादित होता है और dependency()
विधि द्वारा लौटाए गए नकली का उपयोग DependencyImpl
के स्थान पर किया जाता है।
@Replaces
एनोटेशन का उपयोग करना
जैसा कि Sergio ने टिप्पणी अनुभाग में उल्लेख किया है, आप @Replaces
एनोटेशन। निम्नलिखित उदाहरण पर विचार करें:
package di.failure.example;
import io.micronaut.context.annotation.Replaces;
import io.micronaut.test.annotation.MicronautTest;
import org.junit.jupiter.api.Test;
import javax.inject.Inject;
import javax.inject.Singleton;
@MicronautTest
public class ClassUnderTestTest {
@Inject
ClassUnderTest classUnderTest;
@Test
public void test() {
classUnderTest.run();
}
@Replaces(Dependency.class)
@Singleton
public static class MockDependency extends Dependency {
public MockDependency() {
System.out.println("MockDependency.<init>");
}
@Override
void run() {
System.out.println("Does not throw any exception...");
}
}
}
इस उदाहरण में हमने एक वर्ग MockDependency
को परिभाषित किया है और हम माइक्रोनॉट के DI तंत्र को Dependency
बीन को MockDependency
से बदलने का निर्देश देते हैं। हालाँकि, एक महत्वपूर्ण बात हमें याद रखने की आवश्यकता है - क्योंकि हमारा MockDependency
Dependency
वर्ग का विस्तार करता है, माता-पिता का निर्माण लागू हो जाता है। आपने प्रश्न में जो उदाहरण दिखाया है वह इस मामले में काम नहीं करेगा, क्योंकि Dependency.<init>
फेंकता है RuntimeException
और परीक्षण विफल हो जाता है। इस संशोधित उदाहरण में मैंने इस तरह की कक्षा का उपयोग किया है:
package di.failure.example;
import javax.inject.Singleton;
@Singleton
public class Dependency {
public Dependency() {
System.out.println("Dependency.<init>");
}
void run() {
throw new RuntimeException("I don't want this to load!");
}
}
जब मैं परीक्षण चलाता हूं तो यह गुजरता है और मुझे निम्न कंसोल आउटपुट दिखाई देता है:
Dependency.<init>
MockDependency.<init>
Does not throw any exception...
@MockBean
की तुलना में मुख्य अंतर यह है कि @Replaces
के मामले में आप एक ठोस वर्ग वस्तु का उपयोग कर रहे हैं। वर्कअराउंड के रूप में (यदि हमें वास्तव में मॉकिटो मॉक ऑब्जेक्ट की आवश्यकता है) आंतरिक रूप से एक मॉक बनाना है और इस ऑब्जेक्ट को कॉल करना है, कुछ इस तरह:
@Replaces(Dependency.class)
@Singleton
public class MockDependency extends Dependency {
private final Dependency delegate;
public MockDependency() {
this.delegate = mock(Dependency.class);
}
@Override
void run() {
delegate.run();
}
}
संबंधित सवाल
नए सवाल
java
जावा एक उच्च स्तरीय प्रोग्रामिंग भाषा है। इस टैग का उपयोग तब करें जब आपको भाषा का उपयोग करने या समझने में समस्या हो। इस टैग का उपयोग शायद ही कभी किया जाता है और इसका उपयोग अक्सर [वसंत], [वसंत-बूट], [जकार्ता-ई], [Android], [javafx], [हडूप], [श्रेणी] और [मावेन] के साथ किया जाता है।