ज्यूनिट में कई रनवे स्टेटमेंट


113

मैं इकाई परीक्षण लिखता हूं JUnitParamsRunnerऔर MockitoJUnitRunnerएक परीक्षण वर्ग के लिए उपयोग करना चाहता हूं ।

दुर्भाग्य से, निम्नलिखित काम नहीं करता है:

@RunWith(MockitoJUnitRunner.class)
@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
  // some tests
}

क्या एक परीक्षण कक्षा में मॉकिटो और ज्यूनिटपराम दोनों का उपयोग करने का एक तरीका है?



2
यहाँ एक अच्छा उदाहरण भी है: blog.project13.pl/index.php/coding/1077/…
falsarella

जवाबों:


110

आप ऐसा नहीं कर सकते क्योंकि युक्ति के अनुसार आप एक ही एनोटेशन को एक ही एनोटेट तत्व पर दो बार नहीं डाल सकते।

तो समाधान क्या है? इसका उपाय यह है कि आप केवल एक @RunWith()धावक के साथ रखें जिसके बिना आप खड़े नहीं हो सकते और दूसरे को किसी अन्य चीज़ से बदल सकते हैं। आपके मामले में मुझे लगता है कि आप इसे हटा देंगे MockitoJUnitRunnerऔर प्रोग्रामिक रूप से यह करेंगे।

वास्तव में केवल एक चीज जो इसे चलाती है:

MockitoAnnotations.initMocks(test);

परीक्षण मामले की शुरुआत में। इसलिए, इस कोड को setUp()विधि में रखना सबसे सरल उपाय है :

@Before
public void setUp() {
    MockitoAnnotations.initMocks(this);
}

मुझे यकीन नहीं है, लेकिन शायद आपको ध्वज का उपयोग करके इस पद्धति के कई कॉल से बचना चाहिए:

private boolean mockInitialized = false;
@Before
public void setUp() {
    if (!mockInitialized) {
        MockitoAnnotations.initMocks(this);
        mockInitialized = true;  
    }
}

हालांकि बेहतर, पुन: प्रयोज्य समाधान को JUnt के नियमों के साथ लागू किया जा सकता है।

public class MockitoRule extends TestWatcher {
    private boolean mockInitialized = false;

    @Override
    protected void starting(Description d) {
        if (!mockInitialized) {
            MockitoAnnotations.initMocks(this);
            mockInitialized = true;  
        }
    }
}

अब बस अपने परीक्षण वर्ग में निम्न पंक्ति जोड़ें:

@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

और आप इस परीक्षण मामले को किसी भी धावक के साथ चला सकते हैं जिसे आप चाहते हैं।


12
के लिए जाँच mockInitializedगलत है। आप हर टेटस्ट के लिए एक ताजा मॉक करना चाहते हैं।
BetaRide

1
@ बेटराइड, यह आपकी आवश्यकताओं पर निर्भर करता है। कभी-कभी आप हर बार नकली का टीका लगाना चाहते हैं, कभी-कभी नहीं।
एलेक्स

यदि आप प्रति क्लास फ़ाइल एक बार सेट करना चाहते हैं, तो आप पहले के बजाय बीटक्लास का उपयोग कर सकते हैं, जो कि एक बार और केवल एक बार परीक्षण फ़ाइल के अनुसार लागू किया जाएगा।
infernalRapture

56

JUnit 4.7 और मॉकिटो 1.10.17 के रूप में, इस कार्यक्षमता में बनाया गया है; एक org.mockito.junit.MockitoRuleवर्ग है। आप बस इसे आयात कर सकते हैं और लाइन जोड़ सकते हैं

@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

अपने परीक्षण वर्ग के लिए।


2
मॉकिटो के पुराने संस्करणों के लिए (1.10.5 तक नीचे) ऐसा लगता है, आपको उपयोग करना होगा:@Rule public MockitoJUnitRule mockito = new MockitoJUnitRule(this);
क्लिफ सन

MockitoAnnotations.initMocks(this)नकली बनाने के लिए बहुत धीमी है। @Runwith (MockitoJunitRunner.class)
ant2009

16

यह समाधान हर संभव धावक के लिए काम करता है, न कि केवल इस नकली उदाहरण के लिए। उदाहरण के लिए; वसंत के लिए, बस धावक कक्षाएं बदलें और आवश्यक एनोटेशन जोड़ें।

@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {

    @Test
    public void subRunner() throws Exception {
        JUnitCore.runClasses(TestMockitoJUnitRunner.class);
    }

    @RunWith(MockitoJUnitRunner.class)
    public static class TestMockitoJUnitRunner {
    }
}

DatabaseModelTestJUnit द्वारा चलाया जाएगा। TestMockitoJUnitRunnerइस पर निर्भर करता है (तर्क से) और इसे कॉल के दौरान एक विधि में मुख्य के अंदर चलाया जाएगा । यह विधि सुनिश्चित करती है कि उप-धावक के चलने से पहले मुख्य धावक को सही ढंग से शुरू किया जाए , प्रभावी रूप से आश्रित परीक्षण कक्षाओं के साथ कई नेस्टेड एनोटेशन को लागू करना ।@TestJUnitCore.runClasses(TestMockitoJUnitRunner.class)static class TestMockitoJUnitRunner@RunWith

इसके अलावा https://bekce.github.io/junit-multiple-runwith-dependent-tests पर


3
JUnitCore.runClasses()परिणाम का निरीक्षण किए बिना कॉल करके , आप आंतरिक परीक्षण से त्रुटियों को चिह्नित करने का जोखिम उठाते हैं। assert(JUnitCore.runClasses(TestMockitoJUnitRunner.class).wasSuccessful());कम से कम आपको त्रुटि की सूचना देगा
रोबोटिक


2

मेरे मामले में मैं स्प्रिंग बीन में कुछ विधि का उपयोग करने की कोशिश कर रहा था और

MockitoAnnotations.initMocks(test);

काम नहीं करता है। इसके बजाय आपको उस बीन को अपने xml फ़ाइल के अंदर नकली विधि का उपयोग करके निर्माण करना होगा।

...
<bean id="classWantedToBeMocked" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.fullpath.ClassWantedToBeMocked" />
</bean>
...

और उस बीन को अपने टेस्ट क्लास के अंदर ऑटोवार्ड के साथ जोड़ें जैसे कि निम्नलिखित।

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="file:springconfig.xml")
public class TestClass {
    ...
    @Autowired
    private ClassWantedToBeMocked classWantedToBeMocked;
    ...
    when(classWantedToBeMocked.methodWantedToBeMocked()).thenReturn(...);
    ...
}

0

इस लिंक की जाँच करें https://bekce.github.io/junit-multiple-runwith-dependent-tests/ इस दृष्टिकोण का उपयोग करके मैंने एक @RunWith (Parameterized.class) - बाहरी धावक को संयुक्त किया - @RunWith (MockitoJUnitRunner.class) के साथ - आंतरिक धावक। एकमात्र ट्विस्ट जो मुझे जोड़ना था, वह था कि मैं अपने सदस्य चर को बाहरी / धावक स्थैतिक में बनाऊं ताकि उन्हें आंतरिक / नेस्टेड धावक / वर्ग के लिए सुलभ बनाया जा सके। भाग्य का आनंद लें और आनंद लें।


0

मैं SWTBotJunit4ClassRunner और org.junit.runners चलाना चाहता था । उसी समय, मेरे पास पैरामीट्रिक परीक्षण हैं और जब SWT परीक्षण विफल हो जाता है, तो मैं स्क्रीनशॉट लेना चाहता हूं (स्क्रीनशॉट सुविधा SWTBotJunit4ClassRunner द्वारा प्रदान की गई है )। @ bekce का जवाब बहुत अच्छा है और पहले वह उस रास्ते पर जाना चाहता था लेकिन या तो वह बहस से गुजर रहा था। या उपवर्ग में पैराट्राइज्ड कर रहा है और जानकारी खो रहा है कि क्या सटीक परीक्षण पास हुए / असफल हुए और केवल अंतिम स्क्रीनशॉट है (जैसा कि स्क्रीनशॉट नाम परीक्षण से ही नाम मिलता है)। तो किसी भी तरह से यह थोड़ा गड़बड़ था।

मेरे मामले में SWTBotJunit4ClassRunner काफी सरल है, इसलिए मैंने क्लास के सोर्स-कोड को क्लोन किया, इसे मेरा अपना नाम ParametrizedScreenshotRunner दिया और जहाँ मूल टेस्टरूनर बढ़ा रहा था , मेरा क्लास Parameterized क्लास को बढ़ा रहा है, ताकि मैं अपने रनर का उपयोग कर सकूं । पिछले दो के बजाय। नीचे उतारा गया मेरा अपना रनर इसके शीर्ष पर स्क्रीनशॉट फीचर को लागू करते हुए Parameterized रनर के ऊपर फैला हुआ है, अब मेरा परीक्षण इस "हाइब्रिड" रनर का उपयोग करता है और सभी परीक्षण सीधे उम्मीद के अनुसार काम करते हैं (परीक्षणों के अंदर कुछ भी बदलने की आवश्यकता नहीं है)।

यह इस तरह दिखता है (संक्षिप्तता के लिए मैंने सूची से सभी टिप्पणियों को हटा दिया है):

package mySwtTests;

import org.junit.runners.Parameterized;
import org.eclipse.swtbot.swt.finder.junit.ScreenshotCaptureListener;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;

public class ParametrizedScreenshotRunner extends TestRu Parameterized {

    public ParametrizedScreenshotRunner(Class<?> klass) throws Throwable {
        super(klass);
    }

    public void run(RunNotifier notifier) {
        RunListener failureSpy = new ScreenshotCaptureListener();
        notifier.removeListener(failureSpy); // remove existing listeners that could be added by suite or class runners
        notifier.addListener(failureSpy);
        try {
            super.run(notifier);
        } finally {
            notifier.removeListener(failureSpy);
        }
    }
}

-15

आप यह भी आज़मा सकते हैं:

@RunWith(JUnitParamsRunner.class)
public class AbstractTestClass {
  // some tests
}

@RunWith(MockitoJUnitRunner.class)
public class DatabaseModelTest extends AbstractTestClass {
  // some tests
}

2
यह काम नहीं करेगा, केवल उप-वर्ग एनोटेशन संसाधित किया जाएगा।
पॉलएनयूके

काम नहीं करता - केवल MockitoJUnitRunner एनोटेशन को ध्यान में रखा जाएगा
Przemek Bielicki
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.