Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide a full equivalent replacement for the @Rule functionality #1211

Closed
nico-de opened this issue Dec 18, 2017 · 4 comments
Closed

Provide a full equivalent replacement for the @Rule functionality #1211

nico-de opened this issue Dec 18, 2017 · 4 comments

Comments

@nico-de
Copy link

nico-de commented Dec 18, 2017

To my understanding, currently, there's no clean and elegant replacement for all opportunities that could be achieved leveraging @Rule available in JUnit 4.

Here's the idiom how we often implement reusable Rules in order to bootstrap and tear down test servers (e.g. embedded databases or RMI / FTP servers) needed to mock external systems when executing integration tests:

public class TestServer extends ExternalResource {
   private final String fUser;
   private final String fPwd;
   private final String fUrl;

   public TestServer(final String user, final String pwd, final String url) {
      fUser = user;
      fPwd = pwd;
      fUrl = url;
   }

   @Override
   protected void before() {
      System.out.println(String.format("Starting test server ('%s', '%s', '%s') ...", fUser, fPwd, fUrl));
      /* start up test server using the information this object's holding */
      System.out.println("... started test server.");
   }

   @Override
   protected void after() {
      System.out.println(String.format("Shutting down test server ('%s', '%s', '%s') ...", fUser, fPwd, fUrl));
      /* shut down test server using the information this object's holding */
      System.out.println("... shut down test server.");
   }

   public String user() { return fUser; }
   public String pwd() { return fPwd; }
   public String url() { return fUrl; }
}

In the test cases where such a functionality is needed, we just declare a field as follows:

public class JUnit4StatefulRuleTest {

   @Rule
   public final TestServer server = new TestServer("hans", "wurst", "http://localhost:8118");

   @Test
   public void testIt() {
      /* execute (integration) test depending on the test server bootstrapped */
   }
}

When trying to implement this with JUnit 5 using Extensions, i.e. introducing and registering a class implementing BeforeEachCallback and AfterEachCallback, at least three issues come to my mind:

  1. Since we cannot rely on the Extension object's state, we had to use the Store– which is at least cumbersome and counter-intuitive.
  2. During test execution, we often need to query and assert the test server's state, i.e. some object (maybe the Extension itself) representing the test server would have to be declared as a field in the test class. This could be achieved by implementing TestInstancePostProcessor and injecting it. However, there wouldn't be any obvious connection between the field injected and the ExtendWith annotation since the latter can only be applied to types or methods.
  3. There's no – at least to my understanding – clean (i.e. without using reflection) way to pass (initialization) information to the Extension object (how it's done in the TestServer Rule by invoking the ctor).

Am I missing anything here?

@sormuras
Copy link
Member

Hi @nico-de -- comparing your request to #497 ... do they match? Anything missing?

See this almost finished finished feature branch: https://github.com/junit-team/junit5/compare/issues/497-programmatic-extension-registration

@smoyer64
Copy link
Contributor

smoyer64 commented Dec 18, 2017

@nico-de I'm almost done with all the JUnit 4 built-in @Rule equivalent extensions in #660 (a PR from https://github.com/selesy/junit5/tree/issues/343-document-testrule-compatibility). I'm hoping to complete this PR over the Christmas holiday.

More importantly, the code that I originally wrote as examples in that PR will be moving to https://github.com/junit-pioneer/junit-pioneer so that there's a release artifact for these @Rules available in Maven Central.

Related to (duplicate of?) #343.

@nico-de
Copy link
Author

nico-de commented Dec 18, 2017

@sormuras, yes you're right. #497 seems to be exactly what I was striving for. Sorry for filing a duplicate: I searched for a ticket covering my request – but failed to find #497.

@nico-de nico-de closed this as completed Dec 18, 2017
@mmerdes
Copy link
Contributor

mmerdes commented Dec 19, 2017

You can also turn on partial support for JUnit 4 rules via org.junit.jupiter.migrationsupport.rules.EnableRuleMigrationSupport.
Subclasses of ExteralResource are supported verbatim.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants