जवाबों:
हालांकि मैं @assylias से सहमत हूं कि उपयोग @BeforeClass
करना एक क्लासिक समाधान है यह हमेशा सुविधाजनक नहीं होता है। विधि के साथ एनोटेट @BeforeClass
स्थिर होना चाहिए। यह कुछ परीक्षणों के लिए बहुत असुविधाजनक है जिन्हें परीक्षण मामले की आवश्यकता है। उदाहरण के लिए वसंत आधारित परीक्षण जो @Autowired
वसंत संदर्भ में परिभाषित सेवाओं के साथ काम करने के लिए उपयोग करते हैं।
इस मामले में मैं व्यक्तिगत रूप setUp()
से @Before
एनोटेशन के साथ एनोटेट की गई नियमित पद्धति का उपयोग करता हूं और अपने कस्टम static
(!) boolean
ध्वज का प्रबंधन करता हूं :
private static boolean setUpIsDone = false;
.....
@Before
public void setUp() {
if (setUpIsDone) {
return;
}
// do the setup
setUpIsDone = true;
}
setUp()
विधि एक सुपरक्लास में है - इसे हल करने के प्रयास के नीचे एक उत्तर पोस्ट किया है ।
आप उपयोग कर सकते हैं एनोटेशन :BeforeClass
@BeforeClass
public static void setUpClass() {
//executed only once, before the first test
}
TheClassYouWant.class
अपने getClass () कॉल के बजाय उपयोग नहीं कर सकते हैं ? यह वास्तविक जावा है String.class.getName()
:।
JUnit 5 में अब एक @BeforeAll एनोटेशन है:
यह दर्शाता है कि वर्तमान वर्ग या वर्ग पदानुक्रम में एनोटेट पद्धति को सभी @ तरीकों से पहले निष्पादित किया जाना चाहिए; JUnit 4 के @BeforeClass के अनुरूप है। ऐसे तरीके स्थिर होने चाहिए।
JUnit 5 के जीवनचक्र एनोटेशन से लगता है कि अंत में यह सही हो गया है! आप अनुमान लगा सकते हैं कि कौन से एनोटेशन बिना देखे भी उपलब्ध हैं (जैसे @BeforeEach @AfterAll)
@BeforeClass
, यह होने की जरूरत है static
। IMO @ एलेक्सआर का समाधान अच्छे है।
जब setUp()
परीक्षण वर्ग (जैसे AbstractTestBase
नीचे) के सुपरक्लास में होता है, तो स्वीकृत उत्तर को निम्नानुसार संशोधित किया जा सकता है:
public abstract class AbstractTestBase {
private static Class<? extends AbstractTestBase> testClass;
.....
public void setUp() {
if (this.getClass().equals(testClass)) {
return;
}
// do the setup - once per concrete test class
.....
testClass = this.getClass();
}
}
यह एक एकल गैर-स्थिर setUp()
पद्धति के लिए काम करना चाहिए, लेकिन मैं tearDown()
जटिल प्रतिबिंब की दुनिया में भटकाए बिना एक समान उत्पादन करने में असमर्थ हूं ... बाउंटी किसी को भी इंगित कर सकता है जो कर सकता है!
संपादित करें: मुझे सिर्फ डिबगिंग करते समय पता चला कि क्लास को हर टेस्ट से पहले भी तुरंत किया जाता है। मुझे लगता है कि यहाँ @BeforeClass एनोटेशन सबसे अच्छा है।
तुम भी निर्माता पर सेट कर सकते हैं, परीक्षण वर्ग है सब के बाद एक वर्ग। मुझे यकीन नहीं है कि यह एक बुरा अभ्यास है क्योंकि लगभग सभी अन्य तरीकों को एनोटेट किया गया है, लेकिन यह काम करता है। आप इस तरह एक निर्माणकर्ता बना सकते हैं:
public UT () {
// initialize once here
}
@Test
// Some test here...
परीक्षण से पहले ctor को बुलाया जाएगा क्योंकि वे स्थिर नहीं हैं।
इस समाधान का प्रयास करें: https://stackoverflow.com/a/46274919/907576 :
@BeforeAllMethods
/ @AfterAllMethods
एनोटेशन के साथ आप उदाहरण के संदर्भ में टेस्ट क्लास में किसी भी विधि को निष्पादित कर सकते हैं, जहां सभी इंजेक्शन मूल्य उपलब्ध हैं।
मेरा गंदा समाधान है:
public class TestCaseExtended extends TestCase {
private boolean isInitialized = false;
private int serId;
@Override
public void setUp() throws Exception {
super.setUp();
if(!isInitialized) {
loadSaveNewSerId();
emptyTestResultsDirectory();
isInitialized = true;
}
}
...
}
मैं इसे अपने सभी टेस्टकेस में बेस बेस के रूप में उपयोग करता हूं।
यदि आप एक ऐसे चर की घोषणा को बाध्य नहीं करना चाहते हैं जो प्रत्येक उप-प्रकार पर सेट और जाँच की जाती है, तो इसे एक सुपरटाइट में जोड़ा जा सकता है:
public abstract class SuperTest {
private static final ConcurrentHashMap<Class, Boolean> INITIALIZED = new ConcurrentHashMap<>();
protected final boolean initialized() {
final boolean[] absent = {false};
INITIALIZED.computeIfAbsent(this.getClass(), (klass)-> {
return absent[0] = true;
});
return !absent[0];
}
}
public class SubTest extends SuperTest {
@Before
public void before() {
if ( super.initialized() ) return;
... magic ...
}
}
मैंने इस समस्या को इस तरह हल किया:
अपने आधार सार वर्ग में जोड़ें (मेरा मतलब है सार वर्ग जहां आप अपने ड्राइवर को सेटअप में आरंभ करते हैं ) कोड के इस भाग में:
private static boolean started = false;
static{
if (!started) {
started = true;
try {
setUpDriver(); //method where you initialize your driver
} catch (MalformedURLException e) {
}
}
}
और अब, यदि आपकी टेस्ट कक्षाएं बेस एब्स्ट्रैक्ट क्लास -> setUpDriver () पद्धति से चलेंगी, तो पहले @Test प्रति रन केवल एक बार पहले निष्पादित किया जाएगा ।
सभी इनिशियलाइज़ेशन कार्य करने के लिए स्प्रिंग के @PostConstruct मेथड का उपयोग करें और यह विधि किसी भी @ निष्पादित होने से पहले चलती है।