@ পূর্বক্লাস এবং উত্তরাধিকার - মৃত্যুদন্ডের আদেশ order


93

আমার একটি বিমূর্ত বেস ক্লাস রয়েছে, যা আমি আমার ইউনিট পরীক্ষার (টেস্টএনজি 5.10) বেস হিসাবে ব্যবহার করি। এই শ্রেণীর, আমি আমার পরীক্ষার জন্য পুরো পরিবেশ আরম্ভ, ডাটাবেজ ম্যাপিং স্থাপনের ইত্যাদি এই বিমূর্ত বর্গ একটি সঙ্গে একটি পন্থা নেই @BeforeClassটীকা যা আরম্ভের আছে।

এরপরে, আমি নির্দিষ্ট ক্লাসের সাথে সেই ক্লাসটি প্রসারিত করি যেখানে আমার @Testপদ্ধতি এবং @BeforeClassপদ্ধতি রয়েছে। এই পদ্ধতিগুলি পরিবেশের শ্রেণি-নির্দিষ্ট সূচনা করে (উদাহরণস্বরূপ ডাটাবেসে কিছু রেকর্ড রাখে)।

আমি কীভাবে @BeforeClassটীকাযুক্ত পদ্ধতির একটি নির্দিষ্ট ক্রম প্রয়োগ করতে পারি ? আমার বিস্তৃত শ্রেণীর সদস্যগুলির আগে মৃত্যুর জন্য অ্যাবস্ট্রাক্ট বেস শ্রেণীর একটিগুলি দরকার।

উদাহরণ:

abstract class A {
    @BeforeClass
    doInitialization() {...}
}

class B extends A {
    @BeforeClass
    doSpecificInitialization() {...}

    @Test
    doTests() {...}
}

প্রত্যাশিত আদেশ:

A.doInitialization
B.doSpecificInitialization
B.doTests

প্রকৃত অর্ডার:

B.doSpecificInitialization // <- crashes, as the base init is missing
(A.doInitialization        // <---not executed
 B.doTests)                // <-/

উত্তর:


51

করা উচিত @BeforeClassউপর abstractবর্গ। প্রতিটি সাবক্লাস থেকে এটিকে কল করুন।

abstract class A {
    void doInitialization() {}
}

class B extends A {
    @BeforeClass
    void doSpecificInitialization() {
        super.doInitialization();
    }

    @Test
    void doTests() {}
}

দেখে মনে হচ্ছে টেস্টএনজির মতো @BeforeClass(dependsOnMethods={"doInitialization"})- এটি ব্যবহার করে দেখুন।


10
এটিই মূলত আমি এড়াতে চেয়েছিলাম: সুপার (বিমূর্ত) শ্রেণির পদ্ধতিগুলি স্পষ্টভাবে কল করার দরকার নেই। বিশেষত আমারও যেমন ক্লাস রয়েছে, যা এ থেকে উত্তরাধিকার সূত্রে আসে তবে নিজস্ব @ বিফোরক্লাস পদ্ধতি নেই। আমাকে কেবল সেই উদ্দেশ্যে একটি inোকাতে হবে।
ডোমিনিক সন্দজাজা

4
দ্য dependsOnMethodsকার্যসংক্রান্ত কৌতুক করেনি। যদিও আমি একটি "সুপারক্লাস প্রথম" পদ্ধতির পছন্দ করতাম ...
ডোমিনিক সান্দাজা

4
"DependOnMethod" ব্যবহার করার জন্য "doInitialization" "@Test" দিয়ে এ্যানোটেট করা উচিত নয়? যেহেতু টেকনিক্যালি এটি নিজে একটি পরীক্ষা না ... এটা একটা সমস্যা হয়
N3da

@ পূর্বক্লাসের একটি স্থিতির পদ্ধতিটি বর্ননা করা উচিত
ফ্যাব্রিজিও স্টেলাটো

110

সম্পাদনা করুন: নীচে উত্তরটি ইউনাইটের জন্য , তবে আমি এটি যাইহোক এখানে ছেড়ে দেব কারণ এটি সহায়ক হতে পারে।

জুনিট এপিআই অনুসারেজুনিত : "সুপার ক্লাসের @ বিফার ক্লাস পদ্ধতিগুলি বর্তমান শ্রেণীর আগে চালানো হবে।"

আমি এটি পরীক্ষা করেছি এবং এটি আমার পক্ষে কাজ করে বলে মনে হচ্ছে।

তবে, অডিস নীচে যেমন উল্লেখ করেছেন, ইউনাইটের জন্য আপনার থাকা দরকার দুটি পদ্ধতি আলাদা আলাদা করে রাখা দরকার যদিও অন্যথায় করার ফলে কেবলমাত্র সাবক্লাস পদ্ধতি চালিত হবে কারণ পিতামাতাকে ছায়া দেওয়া হবে।


56
যদিও মূল প্রশ্নটি টেস্টএনজি-র জন্য ছিল, আমি ইউনিতের জন্য গুগল করার পরে এখানে পৌঁছেছি এবং আপনার উত্তরটি সহায়তা করেছে - ধন্যবাদ!
টেবিট

10
JUnit এর জন্য আপনার দুটি পদ্ধতি আলাদা আলাদাভাবে নামকরণ করা দরকার যদিও অন্যথায় করার ফলে কেবলমাত্র সাবক্লাস পদ্ধতি চালিত হবে কারণ পিতামাতাকে ছায়া দেওয়া হবে।
ওডিস

4
@ ওডিস, এটি উল্লেখ করার জন্য আপনাকে অনেক ধন্যবাদ আমার সাবক্লাসে "সেটআপ" পদ্ধতিটি যখন সুপারক্লাসের না থাকাকালীন চলছে তখন কেন তা জানার জন্য আমি লড়াই করে যাচ্ছিলাম। আপনি আমাকে মাত্র এক টন উত্তেজনা বাঁচিয়েছেন!
টম কাতুল্লো

আপনি আমার দিন তৈরি করেছেন। ধন্যবাদ!
রাইস

7

আমি publicবিমূর্ত শ্রেণিতে যুক্ত হয়েছি এবং টেস্টএনজি (6.0.1) এর আগে doInitialization () কার্যকর করা হয়েছিল doTestsdoInitialization()আমি publicক্লাস এ থেকে সরিয়ে দিলে টেস্টএনজি কার্যকর করে না

public abstract class A {
 @BeforeClass
 doInitialization() {...}
}

class B extends A {    
 @Test
 doTests() {...}
}

4
এটি সত্য, তবে অপ্রাসঙ্গিক। এই কাজ করে না যখন বর্গ B এছাড়াও একটি আছে @BeforeClass, -annotated পদ্ধতি ওপি এর ক্ষেত্রে হিসাবে।
jpaugh

4
আমিও তাই করেছি। দেখে মনে হচ্ছে বেস পদ্ধতিটি ব্যক্তিগত থাকলে উত্তরাধিকারের অর্ডারটি মিস হয়েছে। ধন্যবাদ!
মনু

6

আমি মাত্র 5.11 দিয়ে আপনার উদাহরণটি ব্যবহার করে দেখেছি এবং প্রথমে বেস ক্লাসের @ বিপরনক্লাস পেয়েছি।

আপনি কি আপনার টেস্টটিঞ্জ। এক্সএমএল ফাইল পোস্ট করতে পারেন? সম্ভবত আপনি সেখানে A এবং B উভয়ই নির্দিষ্ট করে দিচ্ছেন, যখন কেবল বি প্রয়োজনীয়।

টেস্টং-ব্যবহারকারীদের মেলিং-তালিকায় নির্দ্বিধায় অনুসরণ করুন এবং আমরা আপনার সমস্যার নিবিড় নজর দিতে পারি।

- সিড্রিক


4
টেস্টং সংজ্ঞায়িত (স্পষ্টতই) এর জন্য .xML নয়, এটি Eclipse এবং Maven থেকে চালিত।
ডোমিনিক সন্দজাজা

আপনি কীভাবে একে একে গ্রহন থেকে চালাচ্ছেন? বি ক্লাসে রাইট ক্লিক?
সিড্রিক বিস্ট

4

আমি সবেমাত্র পেরিয়েছি এবং এটি অর্জনের আরও একটি উপায় খুঁজে পেয়েছি। বিমূর্ত ক্লাসে বা কেবল ব্যবহার alwaysRunকরুন , আপনার প্রত্যাশার মতো কাজ করে।@BeforeClass@BeforeMethod

public class AbstractTestClass {
    @BeforeClass(alwaysRun = true)
    public void generalBeforeClass() {
        // do stuff
        specificBeforeClass();
    }
}

2

আমি যখন থেকে চালিত: JUnitCore.runClass (TestClass.class); এটি সন্তানের আগে পিতামাতাকে যথাযথভাবে নির্বাহ করবে (আপনাকে সুপারের দরকার নেই etসেটআপব্রোপারক্লাস (); ) আপনি যদি এটি Eclipse থেকে চালান: কোনও কারণে এটি বেস ক্লাস চালাতে ব্যর্থ। চারপাশের কাজ: বেস ক্লাসকে স্পষ্টভাবে কল করুন: ( বেসস্টেস্ট.সেটআপসফিউটারক্লাস (); ) আপনি কোনও অ্যাপ্লিকেশন থেকে চালানোর ক্ষেত্রে বেস ক্লাসে একটি পতাকা রাখতে চান, এটি ইতিমধ্যে সেটআপ রয়েছে কিনা তা নির্ধারণ করতে। সুতরাং এটি কেবল একবারে চালিত হয় যদি আপনি এটি উভয় সম্ভাব্য পদ্ধতি (যেমন ব্যক্তিগত পরীক্ষার জন্য গ্রহন থেকে, এবং বিল্ড রিলিজের জন্য এএনটির মাধ্যমে) চালান run

এটি Eclipse, বা কমপক্ষে অপ্রত্যাশিত ফলাফল সহ একটি ত্রুটি বলে মনে হচ্ছে ..


2

জুনিতের জন্য : যেমন @ ফোর্তেগা উল্লেখ করেছেন: যুজনিত এপিআই অনুসারে: "সুপার ক্লাসের @ বিফার ক্লাস পদ্ধতিগুলি বর্তমান শ্রেণীর আগে চালানো হবে।"

তবে সতর্কতা অবলম্বন করুন যে উভয় পদ্ধতির নাম একই নাম নয় । যেহেতু এই ক্ষেত্রে পিতামাতার পদ্ধতিটি শিশু পিতামাতার দ্বারা গোপন করা হবে। উত্স


1

আপনার @ বিফোরক্লাস পদ্ধতিটি একটি খালি নির্দিষ্টবিফোরক্লাস () পদ্ধতি কল করতে পারে যা এই জাতীয় সাব ক্লাস দ্বারা ওভাররাইট করা যেতে পারে বা নাও করতে পারে:

public class AbstractTestClass {
  @BeforeClass
  public void generalBeforeClass() {
    // do stuff
    specificBeforeClass();
  }

  protected void specificBeforeClass() {}
}

public class SpecificTest {
  @Override
  protected void specificBeforeClass() {
    // Do specific stuff
  }

  // Tests
}

4
পূর্বেক্লাস অবশ্যই স্থির থাকতে হবে তাই আপনি জুনিট
ম্যাডেক্সের

1

dependsOnMethod ব্যবহার করা যেতে পারে.

যেমন বসন্তের ক্ষেত্রে ( AbstractTestNGSpringContextTests)

@BeforeClass(alwaysRun = true, dependsOnMethods = "springTestContextPrepareTestInstance")

1

আপনার আমদানির বিবৃতি পরীক্ষা করুন। এটা করা উচিত

import org.testng.annotations.BeforeClass;

না

import org.junit.BeforeClass;


1

এটি আমার পক্ষে কাজ করে -

abstract class A {
    @BeforeClass
    doInitialization() {...}
}

class B extends A {
    @Override
    @BeforeClass
    doInitialization() { 

       //do class specific init

    }   

    @Test
    doTests() {...}
}

4
এই কোডটি কী করে তার একটি সংক্ষিপ্ত বিবরণ যুক্ত করুন এবং আসল প্রশ্নের উত্তর দিন
ক্রে

0

আপনি কেন আপনার সুপার ক্লাসে একটি বিমূর্ত পদ্ধতি doSpecialInit () তৈরি করার চেষ্টা করবেন না, আপনার সুপারক্লাসে আপনার বিয়ারক্লাস টীকাযুক্ত পদ্ধতি থেকে ডাকা হয়েছে।

সুতরাং আপনার শ্রেণীর উত্তরাধিকার সূত্রে বিকাশকারীরা এই পদ্ধতিটি প্রয়োগ করতে বাধ্য।


সত্যি কথা বলতে, আমি এই প্রশ্নটি জিজ্ঞাসা করার পরেও যুক্তিটি গত 3 1/2 বছরের মধ্যে পরিবর্তিত হতে পারে ... ;-) তাই হ্যাঁ, সম্ভবত এটি একটি ধারণা ছিল, সম্ভবত এটি কার্যকর হয়নি - আমি সত্যই এটি করি না মনে আছে
ডোমিনিক স্যান্ডজাজা

0

এখানে আরও একটি সহজ সমাধান রয়েছে।

আমার বিশেষ পরিস্থিতিটি হ'ল সুপারক্লাসে "বিয়ারক্লাস" চালিত হওয়ার আগে আমাকে সাবক্লাসে "বিডারক্লাস" থেকে মক পরিষেবাগুলি ইনজেক্ট করা দরকার।

এটি করতে - কেবল @ClassRuleসাবক্লাসে একটি ব্যবহার করুন ।

উদাহরণ স্বরূপ:

@ClassRule
public static ExternalResource mocksInjector = new ExternalResource() {
    @Override
    protected void before() {
        // inject my mock services here
        // Note: this is executed before the parent class @BeforeClass
    }
};

আশা করি এটা কাজে লাগবে. এটি কার্যকরভাবে "বিপরীত" ক্রমে স্থিতিশীল সেটআপ কার্যকর করতে পারে।


0

আমি আজ একই ধরণের সমস্যার মুখোমুখি হয়েছি, কেবলমাত্র পার্থক্যটি ছিল বেস ক্লাসটি বিমূর্ত ছিল না

আমার মামলা এখানে

public class A {
    @BeforeClass
    private void doInitialization() {...}
}

public class B extends A {
    @BeforeClass
    private void doSpecificInitialization() {...}

    @Test
    public void doTests() {...}
}

এটি ঘটেছে যে @BeforeClassA ম শ্রেণীর কোনও পদ্ধতি কখনও কার্যকর করা হয়নি।

  • এ.অনাইটালাইজেশন () -> এটি নিঃশব্দে কার্যকর হয়নি
  • বিডোস্পেসিফিকেশনালাইজেশন ()
  • বিডো টেস্টস ()

গোপনীয়তা সংশোধনকারীদের সাথে খেলে আমি দেখতে পেয়েছি যে টেস্টএনজি উত্তরাধিকার সূত্রে প্রাপ্ত শ্রেণি থেকে কোনও টীকাযুক্ত পদ্ধতি কার্যকর করবে না@BeforeClass যদি কোনও পদ্ধতি শ্রেণি-উত্তরাধিকারীর থেকে দৃশ্যমান না হয়

সুতরাং এটি কাজ করবে:

public class A {
    @BeforeClass
    private void doInitialization() {...}
}

public class B extends A {
    @BeforeClass
    //Here a privacy modifier matters -> please make sure your method is public or protected so it will be visible for ancestors
    protected void doSpecificInitialization() {...}

    @Test
    public void doTests() {...}
}

ফলস্বরূপ নিম্নলিখিতটি ঘটে:

  • এ।
  • বিডোস্পেসিফিকেশনালাইজেশন ()
  • বিডো টেস্টস ()

-1

আমার ক্ষেত্রে (জুনিত) আমার বেস ক্লাস এবং উত্পন্ন ক্লাসে সেটআপ () নামক একই পদ্ধতি রয়েছে। এই ক্ষেত্রে কেবল উত্পন্ন শ্রেণীর পদ্ধতিটি বলা হয়, এবং আমার কাছে এটি বেস ক্লাস পদ্ধতি বলে call


-2

উত্তরাধিকার ব্যবহার করে এটি অর্জনের একটি আরও ভাল এবং ক্লিনার উপায় নিম্নলিখিত হিসাবে হতে পারে -

abstract class A {

    @BeforeClass
    void doInitialization() {}
}

class B extends A {

    @Override
    @BeforeClass
    void doInitialization() {
        super.doInitialization();
    }

    @Test
    void doTests() {}
}

4
আপনার যদি প্যারেন্ট ক্লাসে পদ্ধতিটি কার্যকর করার প্রয়োজন হয় তবে প্রথমে আপনার কেবলমাত্র শিশু শ্রেণিতে পদ্ধতিটির নাম পিতামাতার থেকে আলাদাভাবে রাখা দরকার (কারণ তাদের যদি একই স্বাক্ষর থাকে তবে পলিমারফিজমটি কার্যকর হয়)। আমি বিশ্বাস করি এটি একটি পরিষ্কার উপায়।
আনাতোলি স্টেপানিউক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.