webcompere / system-stubs

System Stubs - Test Doubles for Java System resources
MIT License
91 stars 10 forks source link

I want to use @SystemStub with @Order #77

Closed hkawa608 closed 9 months ago

ashleyfrieze commented 10 months ago

@hkawa608 - please provide an example Unit Test with a description of how you expect it to work differently to the default behaviour of SystemStubs.

ashleyfrieze commented 10 months ago

@hkawa608 - I'll close this in a week if I don't hear from you. It's important to provide more than a title if you have an issue that you'd like someone from an OS project to help you with.

hkawa608 commented 10 months ago

I'm sorry for missing an example and a late response. This is an example. I want to use EnvironmentVariables with a combination of another extension in a certain order.

class Test {

  @RegisterExtension
  @Order(1)
  private final EnvironmentVariables environmentVariables = new EnvironmentVariables().set("TEST_HOME", TEST_HOME);

  @Order(2)
  @RegisterExtension
  private JerseyTestExtension jte = JerseyTestExtension.of(TestApp.class);

  private static final String TEST_HOME = "/etc/test/jre/";

  @Test
  void testApp() throws Exception {

      assertThat(System.getenv("TEST_HOME"), is(TEST_HOME));
    }
  }
ashleyfrieze commented 10 months ago

@hkawa608 in the above code, you're not using@ExtendWith(SystemStubsExtension.class) on the class, so System Stubs won't be active. What happens when you use @ExtendWith here?

hkawa608 commented 10 months ago

Even we use @ExtendWith(SystemStubsExtension.class), it requires @SystemStubs to EnvironmentVariables, so @Order is not effective.

ashleyfrieze commented 9 months ago

To be clear, I'd expect

@ExtendWith(SystemStubsExtension.class)
class MyTest {
    @SystemStub
    private EnvironmentVariables env = new EnvironmentVariables("TEST_HOME", "testhome");

    ...
}

I don't think @RegisterExtension will work with system stubs as per your code...

Note you can make this EnvironmentVariables field static so it works at a higher scope than your instance field of JerseyTestExtension.

As things stand with your example code, it would fail to pass because you're not using system stubs correctly.

It seems you're hoping that SystemStubs could be used as a JUnit extension. Is this necessary?

ashleyfrieze commented 9 months ago

@hkawa608 - have you tried this:

class Test {
  private static final String TEST_HOME = "/etc/test/jre/";

  // set the execution order of the extensions
  @RegisterExtension
  @Order(1)
  private SystemStubsExtension systemStubsExtension = new SystemStubsExtension();

  @Order(2)
  @RegisterExtension
  private JerseyTestExtension jte = JerseyTestExtension.of(TestApp.class);

  // use Environment variables within the system stubs extension
  @SystemStubs
  private EnvironmentVariables environmentVariables = new EnvironmentVariables().set("TEST_HOME", TEST_HOME);

  @Test
  void testApp() throws Exception {
      assertThat(System.getenv("TEST_HOME"), is(TEST_HOME));
  }
}

I think the above is valid... but... I think you really want the environment to be set before the jersey extension does its thing. It's possible that this won't happen the way you want owing to the JerseyExtension perhaps setting itself up before the test runs. The system stubs extension only makes the environment "active" during a test.

You could fix that by either asking system stubs to operate on a static field, where it's in the beforeAll lifecycle, rather than before each.

Or, use a nested test for the jersey bit and do the system stubs stuff in the outer class.

ashleyfrieze commented 9 months ago

@hkawa608 - I'm going to close this issue in a week, since I think there's user error in here. I think you were trying to use EnvironmentVariables as an extension, where it's not.

However, if you can provide me with the link to where you get JerseyTestExtension from - assuming it's a public project - I could potentially add a code example of how to use it.