ক্লাসের আগে জুনিট (অ স্থির)


84

জুনিট কোনও পরীক্ষার ফাইলে একবার কোনও ক্রিয়াকলাপ সম্পাদন করার জন্য কি কোনও সেরা অনুশীলন রয়েছে এবং এটি স্থিরও হওয়া উচিত নয়।

মত @BeforeClassঅ স্ট্যাটিক ফাংশন উপর?

এখানে একটি কুরুচিপূর্ণ সমাধান:

@Before void init(){
    if (init.get() == false){
        init.set(true);
        // do once block
    }
}

ভাল এটি আমি করতে চাই না এমন একটি জিনিস, এবং আমি একটি সংহত জুনিট সমাধান খুঁজছি।


ভাল, আমার কাছে টেস্ট ফাইল এবং বেস টেস্ট ফাইলগুলির একটি বৃহত স্তরক্রম রয়েছে, চাইল্ড টেস্ট ক্লাসে এই ক্রিয়াটি ওভাররাইড করার জন্য আমার সম্ভাবনা দরকার।
রোমান

4
আমার একই সমস্যা ছিল যার মধ্যে অনেকগুলি প্যারামেট্রাইজড পরীক্ষার মধ্যে প্রথমটিতে একটি লগইন করা উচিত।
dokaspar

4
মনে রাখবেন যে "কুরুচিপূর্ণ" সমাধানটি, সরল JUnit এর সাথে কাজ করে, টিয়ারিং টেস্টগুলি অ্যাকাউন্টে নেবে না।
এসকেটোস

উত্তর:


22

আপনি যদি এককালীন সূচনার জন্য স্ট্যাটিক ইনিশিয়ালাইজার স্থাপন করতে না চান এবং JUnit ব্যবহার সম্পর্কে বিশেষ না হন, তবে টেস্টএনজি দেখুন। টেস্টএনজি বিভিন্ন টিকেট ব্যবহার করে বিভিন্ন কনফিগারেশন বিকল্পের সাথে অ স্থিতিশীল, এককালীন সূচনা সমর্থন করে।

টেস্টএনজিতে এটি সমান হবে:

@org.testng.annotations.BeforeClass
public void setUpOnce() {
   // One time initialization.
}

টিয়ারডাউন,

@org.testng.annotations.AfterClass
public void tearDownOnce() {
   // One time tear down.
}

JUnit 4 এর সমতুল্য টেস্টএনজির জন্য @Beforeএবং @Afterআপনি যথাক্রমে @BeforeMethodএবং ব্যবহার করতে পারেন @AfterMethod


41

একটি সাধারণ যদি বিবৃতিটি খুব ভালভাবে কাজ করে বলে মনে হয়:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:test-context.xml"})
public class myTest {

    public static boolean dbInit = false;

    @Autowired
    DbUtils dbUtils;

    @Before
    public void setUp(){

        if(!dbInit){

            dbUtils.dropTables();
            dbUtils.createTables();
            dbInit = true;

        }
    }

 ...

4
সুন্দর এবং সহজ! কিন্তু @AfterClassসমস্ত পরীক্ষা চালিয়ে যাওয়ার পরে চোখের জল ফেলে আসা অ-স্থিতিশীল সমতুল্য করার জন্য এটিকে কেবল রূপান্তর করার কোনও উপায় দেখতে পাচ্ছেন না ?
স্টিভ চেম্বারস

4
এই পদ্ধতির আপডেটের জন্য এখানে দেখুন যা উত্তরাধিকার ব্যবহার করে এমন পরীক্ষার ক্লাসগুলির জন্য কাজ করা উচিত।
স্টিভ চেম্বারস

36

খালি কনস্ট্রাক্টর ব্যবহার করা সহজ সমাধান। আপনি এখনও বর্ধিত শ্রেণিতে কনস্ট্রাক্টরকে ওভাররাইড করতে পারেন।

তবে এটি সমস্ত উত্তরাধিকারের সাথে অনুকূল নয়। এজন্য JUnit 4 এর পরিবর্তে টীকা ব্যবহার করে।

আরেকটি বিকল্প হ'ল কারখানা / ব্যবহারের শ্রেণিতে একটি সহায়ক পদ্ধতি তৈরি করা এবং সেই পদ্ধতিটি কাজটি করতে দেওয়া।

আপনি যদি স্প্রিং ব্যবহার করছেন তবে আপনার @TestExecutionListenersটীকাটি ব্যবহার করা উচিত । এই পরীক্ষার মতো কিছু:

@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({CustomTestExecutionListener.class, 
     DependencyInjectionTestExecutionListener.class})
@ContextConfiguration("test-config.xml")
public class DemoTest {

স্প্রিং এর AbstractTestExecutionListenerউদাহরণস্বরূপ এই ফাঁকা পদ্ধতি যা আপনি ওভাররাইড করতে পারেন:

public void beforeTestClass(TestContext testContext) throws Exception {
    /* no-op */
}

দ্রষ্টব্য:DependencyInjectionTestExecutionListener কাস্টম যুক্ত করার সময় অবহেলা / মিস করবেন না TestExecutionListeners। আপনি যদি করেন তবে সমস্ত অটোয়ার হবে null


+1 DbUnit ব্যবহার করতে চাইলে এবং এই ক্লাসটি কেবলমাত্র ক্লাসে একবার ডেটাসেট লোড করতে চাইলে এই কৌশলটি আমার সমস্যার সমাধান করেছে
ব্র্যাড

+1 বসন্তের প্রাচীন সংস্করণে আবদ্ধ নয় এমন লোকদের জন্য এটি উপযুক্ত ... :(
মাইক মিলার

4
beforeTestClass()প্রসঙ্গটি শুরু হওয়ার আগে বা পরে এগুলি বলা হবে ?
দিমস

@ প্রসঙ্গটি শুরু হওয়ার পরে ডিমগুলি
আনন্দ রকজ্জ

7

ইনস্ট্যান্স প্রসঙ্গে (অ স্থিতিশীল) অভ্যন্তরের কোনও পদ্ধতি চালানোর জন্য সহজেই এনটোটেশনগুলি ব্যবহার করুন @BeforeAllMethods/ @AfterAllMethodsটীকাগুলি যেখানে সমস্ত ইনজেকশনের মান উপলব্ধ থাকবে।

এর জন্য একটি বিশেষ পরীক্ষার পাঠাগার রয়েছে:

https://mvnrepository.com/artifact/org.bitbucket.radistao.test/before- after-spring-test-runner/0.1.0.0

https://bitbucket.org/radistao/before- after-spring-test-runner/

একমাত্র সীমাবদ্ধতা: কেবল বসন্ত পরীক্ষার জন্য কাজ করে ।

(আমি এই পরীক্ষার লাইব্রেরির বিকাশকারী)


0

আমি কখনও চেষ্টা করি নি তবে সম্ভবত আপনি কোনও যুক্তিযুক্ত কনস্ট্রাক্টর তৈরি করতে পারেন এবং সেখান থেকে আপনাকে কল করতে পারেন?


এটি কাজ করবে, সমস্যাটি হ'ল এই বেস পরীক্ষার ক্লাসগুলিকে প্রসারিত ক্লাসগুলিতে এই ক্রিয়াকে ওভাররাইড করার আমার সম্ভাবনা দরকার
রোমান

@ রোমন: ওহ, এখন দেখছি। এটি আপনার পোস্টে যুক্ত করুন, এই মন্তব্যটি বিষয়গুলিকে আরও স্পষ্ট করে তোলে।
রোমান

পরীক্ষার যতবার সমস্যা আছে ততবার কনস্ট্রাক্টরকে ডাকা হবে। প্রতিটি পরীক্ষার পদ্ধতির জন্য নতুন পরীক্ষার শ্রেণীর অবজেক্ট তৈরি করা হবে। সুতরাং, কনস্ট্রাক্টর ব্যবহার করা এখানে কোনও সমাধান নয়
মানিকান্ত

এছাড়াও এই অভ্যাস নির্ভরতা ইনজেকশন নিয়ে কাজ করে যা ইতিমধ্যে নির্মিত বস্তুর উপর নির্ভর করে।
মাইক মিলার

0

নিবন্ধটি এই সমস্যার 2 টি খুব সুন্দর সমাধান নিয়ে আলোচনা করেছে:

  1. কাস্টম রানার দিয়ে "ক্লিন" জুনিট
  2. এস্পেনের আগে যেমন উল্লেখ করা হয়েছে বসন্ত সম্পাদন শ্রোতারা।

0

আপডেট: নীচের পরামর্শটি ত্রুটিযুক্ত কেন দয়া করে চেরির মন্তব্য দেখুন। (মন্তব্যটি মুছে ফেলার পরিবর্তে উত্তরটি এখানে রাখছি কারণ অন্যেরা কেন এটি কাজ করে না তা দরকারী তথ্য সরবরাহ করতে পারে ।)


নির্ভরতা ইনজেকশন (উদাহরণস্বরূপ স্প্রিং) ব্যবহার করা হয় কিনা তা বিবেচনা করার মতো অন্য বিকল্প @PostConstruct। এটি নির্ভরতা ইনজেকশন সম্পূর্ণরূপে গ্যারান্টি দেবে, যা কোনও নির্মাণকারীর ক্ষেত্রে হবে না:

@PostConstruct
public void init() {
    // One-time initialization...
}


7
জুনিট পরীক্ষার ক্ষেত্রে খুব খারাপ সমাধান। জুনিট পরীক্ষার শ্রেণীর উদাহরণ তৈরি করে যখনই এটি কোনও পরীক্ষা পদ্ধতি চালায়। সুতরাং ক্লাসে 6 টি পরীক্ষার পদ্ধতি থাকলে একটি শ্রেণি নির্মাতা @Beforeএবং @Afterপদ্ধতিগুলি 6 বার বলা হবে! সুতরাং এই প্রসঙ্গে টীকা দেওয়ার @PostConstructমতো আচরণ করে @Before। আপনি কেবল এটি পরীক্ষা করতে পারেন: পরীক্ষার শ্রেণিতে 2 টি পরীক্ষা পদ্ধতি রাখুন, এটি কতবার @PostConstruct public void init() {System.out.println("started");}মুদ্রিত হয় তা লগগুলিতে যুক্ত করে দেখুন।
চেরি

তথ্যের জন্য আমি JUnit ডকুমেন্টেশন জুড়ে এসেছি যা Junnit সম্পর্কে প্রতিটি @Testরানের জন্য একটি উদাহরণ তৈরি করার বিষয়ে উপরের মন্তব্যে বর্ণিত যা আছে তা নিশ্চিত করে : "পদ্ধতিটি চালানোর জন্য, ইউনিত প্রথমে ক্লাসের একটি নতুন ঘটনা তৈরি করে তারপরে এনোটোটেড পদ্ধতিটি প্রেরণ করে।"
স্টিভ চেম্বারস

-2

শুধু ব্যবহার করুন @BeforeClass:

@BeforeClass
public static void init() {
}

initঅ-স্থিতিশীল হওয়ার কোনও অর্থ হয় না কারণ প্রতিটি পরীক্ষা পৃথক ক্ষেত্রে চালিত হয় in যে উদাহরণটি initচালু আছে তা কোনও পরীক্ষার উদাহরণের সাথে মেলে না।

আপনি এটি অ-স্থির হতে পারে এমন একমাত্র কারণ এটি সাবক্লাসে ওভাররাইড করা, তবে আপনি স্থির পদ্ধতিতেও এটি করতে পারেন। কেবল একই নামটি ব্যবহার করুন এবং কেবলমাত্র সাবক্লাস initপদ্ধতিটি কল করা হবে।


4
এই পুরো প্রশ্নটি অ-স্থিতিশীল উপায়ে এটি করার সম্ভাবনা সম্পর্কে, যা আপনার ক্লাসে কিছু উদাহরণ-পরিবর্তনশীল প্রয়োজন হলে এটি প্রয়োজন।
সাইমন ফোর্সবার্গ

@ সিমোনফারসবার্গ হ্যাঁ, এবং আমি বলছি যে প্রশ্নটি একটি এক্সওয়াই সমস্যা। অপ বলেন যে সমস্যাটি শিশু শ্রেণির আচরণগুলিকে অগ্রাহ্য করছে। উদাহরণে যদি উদাহরণের পরিবর্তনশীলগুলির প্রয়োজন হয় তবে আমি অন্য কিছু প্রস্তাব দিতে পারি।
fgb


@ সিমোনফারসবার্গ এটাই যে মন্তব্য আমি বলছিলাম। এটা কেমন?
fgb
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.