Home > Mobile >  How to replace @Rule in JUNIT5
How to replace @Rule in JUNIT5

Time:11-11

I want to convert this piece of code in JUNIT 5 without using @Rule. I tried JUINT 5 TestWatcher but it doens't have starting method. tried with this but not able to understand how to implement ExtendWith or Extension

 @Rule
    public TestWatcher watchman = new TestWatcher() {
    
        @Override
        public void starting(final Description description) {
            logger.info("STARTING test: "   description.getMethodName());
        }
    };

CodePudding user response:

For more information about JUnit 5, I suggest reading the JUnit 5 User Guide.


In JUnit 5, if you want to execute a method before each test, then you can use the @BeforeEach annotation. To get information about the test to be executed you can give the method a TestInfo parameter which will be automatically injected for you. For example:

import java.lang.reflect.Method;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
// import logger...

class XXXTests {

  final Logger logger = ...;

  @BeforeEach
  void logStartOfTest(TestInfo info) {
    logger.info("STARTING test: "   info.getMethod().map(Method::getName).orElse(null));
  }

  @Test
  void testFoo() {
    // perform assertions
  }
}

If you don't want to have to write that for every test, then you can create your own extension that implements BeforeEachCallback. For example:

import java.lang.reflect.Method;
import org.junit.jupiter.api.extension.BeforeEachCallback;
import org.junit.jupiter.api.extension.ExtensionContext;
// import logger..

public class MyExtension implements BeforeEachCallback {

    final Logger logger = ...;

    @Override
    public void beforeEach(ExtensionContext context) {
        logger.info("STARTING test: "   context.getTestMethod().map(Method::getName).orElse(null));
    }
}

Then apply your extension:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(MyExtension.class)
class XXXTests {

    @Test
    void testFoo() {
        // perform assertions
    }
}

Your extension class can implement multiple extension interfaces. If you want to watch for success and failure, then you can also implement org.junit.jupiter.api.extension.TestWatcher, but note that interface only became stable API in JUnit 5.7 (I believe it was added in version 5.4).

CodePudding user response:

Junit 5 has its own definition of an interface called TestWatcher – see User Guide – but it doesn't have a method equivalent to JUnit 4's starting method. Instead, what you had in the starting method in JUnit 4 can go into the @BeforeEach method of JUnit 5, and for the remaining methods (such as those handling test success and failure) you can implement this interface and override its methods (such as testSuccessful and testFailed) and then use your extension class with the @ExtendWith annotation like this:

@ExtendWith(MyTestWatcher.class)
class MyTestClass {
    ...
}
  • Related