@BeforeClass and inheritance - order of execution

前端 未结 16 2039
梦如初夏
梦如初夏 2020-12-02 11:39

I have an abstract base class, which I use as a base for my unit tests (TestNG 5.10). In this class, I initialize the whole environment for my tests, setting up database map

相关标签:
16条回答
  • 2020-12-02 12:22

    There is another easy solution here.

    My particular situation is that I need to inject mock services from "BeforeClass" in the subclass before "BeforeClass" in the superclass is executed.

    To do this - simply use a @ClassRule in the subclass.

    For example:

    @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
        }
    };
    

    I hope this helps. This can effectively execute static setup in "reverse" order.

    0 讨论(0)
  • 2020-12-02 12:24

    edit: Answer below is for JUnit, but I will leave it here anyway, because it could be helpful.

    According to the JUnit api: "The @BeforeClass methods of superclasses will be run before those the current class."

    I tested this, and it seems to work for me.

    However, as @Odys mentions below, for JUnit you need to have the two methods named differently though as doing otherwise will result in only the subclass method being run because the parent will be shadowed.

    0 讨论(0)
  • 2020-12-02 12:24

    I just tried your example with 5.11 and I get the @BeforeClass of the base class invoked first.

    Can you post your testng.xml file? Maybe you are specifying both A and B there, while only B is necessary.

    Feel free to follow up on the testng-users mailing-list and we can take a closer look at your problem.

    -- Cedric

    0 讨论(0)
  • 2020-12-02 12:29

    Don't put the @BeforeClass on the abstract class. Call it from each subclass.

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

    Seems like TestNG has @BeforeClass(dependsOnMethods={"doInitialization"}) - give it a try.

    0 讨论(0)
  • 2020-12-02 12:29

    Why don't you try to create an abstract method doSpecialInit() in your super class, called from your BeforeClass annotated method in superclass.

    So developpers inheriting your class is forced to implement this method.

    0 讨论(0)
  • 2020-12-02 12:30

    Check your import statement. It should be

    import org.testng.annotations.BeforeClass;

    not

    import org.junit.BeforeClass;

    0 讨论(0)
提交回复
热议问题