मोक्स इनिशियलाइज़ेशन के लिए , रनर का उपयोग कर रहे हैं या MockitoAnnotations.initMocks
कड़ाई से समकक्ष समाधान हैं। MockitoJUnitRunner के javadoc से :
JUnit 4.5 runner initializes mocks annotated with Mock, so that explicit usage of MockitoAnnotations.initMocks(Object) is not necessary. Mocks are initialized before each test method.
MockitoAnnotations.initMocks
जब आप पहले से ही एक विशिष्ट धावक ( SpringJUnit4ClassRunner
उदाहरण के लिए) को अपने परीक्षण के मामले में कॉन्फ़िगर कर चुके हैं, तो पहले समाधान (के साथ ) का उपयोग किया जा सकता है ।
दूसरा समाधान (के साथ MockitoJUnitRunner
) अधिक क्लासिक और मेरा पसंदीदा है। कोड सरल है। रनर का उपयोग करने से फ्रेमवर्क उपयोग के स्वत: सत्यापन का शानदार लाभ मिलता है ( इस उत्तर में @ डेविड वैलेस द्वारा वर्णित )।
दोनों समाधान परीक्षण विधियों के बीच मोज़ेक (और जासूस) को साझा करने की अनुमति देते हैं। के साथ युग्मित @InjectMocks
, वे बहुत जल्दी इकाई परीक्षण लिखने की अनुमति देते हैं। बॉयलरप्लेट मॉकिंग कोड कम हो गया है, परीक्षण पढ़ने में आसान हैं। उदाहरण के लिए:
@RunWith(MockitoJUnitRunner.class)
public class ArticleManagerTest {
@Mock private ArticleCalculator calculator;
@Mock(name = "database") private ArticleDatabase dbMock;
@Spy private UserProvider userProvider = new ConsumerUserProvider();
@InjectMocks private ArticleManager manager;
@Test public void shouldDoSomething() {
manager.initiateArticle();
verify(database).addListener(any(ArticleListener.class));
}
@Test public void shouldDoSomethingElse() {
manager.finishArticle();
verify(database).removeListener(any(ArticleListener.class));
}
}
पेशेवरों: कोड न्यूनतम है
विपक्ष: काला जादू। IMO यह मुख्य रूप से @InjectMocks एनोटेशन के कारण है। इस एनोटेशन के साथ "आप कोड के दर्द को ढीला करते हैं" ( @Brice की शानदार टिप्पणियाँ देखें )
तीसरा उपाय यह है कि प्रत्येक परीक्षा पद्धति पर अपना मॉक बनाएं। यह अपने जवाब में " एमएलके द्वारा " आत्म निहित परीक्षण करने के लिए समझाया गया है ।
public class ArticleManagerTest {
@Test public void shouldDoSomething() {
// given
ArticleCalculator calculator = mock(ArticleCalculator.class);
ArticleDatabase database = mock(ArticleDatabase.class);
UserProvider userProvider = spy(new ConsumerUserProvider());
ArticleManager manager = new ArticleManager(calculator,
userProvider,
database);
// when
manager.initiateArticle();
// then
verify(database).addListener(any(ArticleListener.class));
}
@Test public void shouldDoSomethingElse() {
// given
ArticleCalculator calculator = mock(ArticleCalculator.class);
ArticleDatabase database = mock(ArticleDatabase.class);
UserProvider userProvider = spy(new ConsumerUserProvider());
ArticleManager manager = new ArticleManager(calculator,
userProvider,
database);
// when
manager.finishArticle();
// then
verify(database).removeListener(any(ArticleListener.class));
}
}
पेशेवरों: आप स्पष्ट रूप से प्रदर्शित करते हैं कि आपके एपीआई कैसे काम करते हैं (बीडीडी ...)
विपक्ष: अधिक बॉयलरप्लेट कोड है। (मोक्स क्रिएशन)
मेरी सिफारिश एक समझौता है। के @Mock
साथ एनोटेशन का उपयोग करें @RunWith(MockitoJUnitRunner.class)
, लेकिन इसका उपयोग न करें @InjectMocks
:
@RunWith(MockitoJUnitRunner.class)
public class ArticleManagerTest {
@Mock private ArticleCalculator calculator;
@Mock private ArticleDatabase database;
@Spy private UserProvider userProvider = new ConsumerUserProvider();
@Test public void shouldDoSomething() {
// given
ArticleManager manager = new ArticleManager(calculator,
userProvider,
database);
// when
manager.initiateArticle();
// then
verify(database).addListener(any(ArticleListener.class));
}
@Test public void shouldDoSomethingElse() {
// given
ArticleManager manager = new ArticleManager(calculator,
userProvider,
database);
// when
manager.finishArticle();
// then
verify(database).removeListener(any(ArticleListener.class));
}
}
पेशेवरों: आप स्पष्ट रूप से प्रदर्शित करते हैं कि आपकी एपीआई कैसे काम करती है (कैसे मेरी ArticleManager
तत्काल है)। कोई बॉयलरप्लेट कोड नहीं।
विपक्ष: परीक्षण आत्म निहित नहीं है, कोड का कम दर्द