-1

From the documentation:

public class SimpleExpectedExceptionTest {
     @Rule
     public ExpectedException thrown= ExpectedException.none();

     @Test
     public void throwsNothing() {
         // no exception expected, none thrown: passes.
     }

     @Test
     public void throwsExceptionWithSpecificType() {
         thrown.expect(NullPointerException.class);
         throw new NullPointerException();
     }
 }

Is valid. But what if the tests were run in a different order? Does the @Rule annotation tell JUnit to reset its state after each test?

djechlin
  • 59,258
  • 35
  • 162
  • 290

2 Answers2

2

Yes, the rule is reset for every single test that is run.

One of the key things about JUnit is that tests are never dependant upon order

tddmonkey
  • 20,798
  • 10
  • 58
  • 67
  • One test could set a global variable (like a System flag) the other reads, which creates an order coupling. I don't know why that doesn't happen with ExpectedException. – djechlin Jan 09 '15 at 17:24
  • 1
    @AAA JUnit documents how your tests cases should be set up. If a developer does something differently, that's their problem. After all, you're using a tool. Use it as intended. If you don't, you can't expect anything. – Sotirios Delimanolis Jan 09 '15 at 17:32
  • @SotiriosDelimanolis okay, so, how am I supposed to use ExpectedException? – djechlin Jan 09 '15 at 18:30
  • @SotiriosDelimanolis and my point was more that the logic in this answer is wrong as stated. You seem to agree with me, by saying JUnit doesn't guarantee these things and the developer is expected to do it correctly. – djechlin Jan 09 '15 at 18:32
  • @AAA - For things other than `Rules`, test should be very careful to reset state to ensure no interaction b/w tests. However, the `Rule` annotation is used in JUnit and Rules are implemented such that they reset themselves before each test so for Rules you don't have to worry about interaction. – John B Jan 09 '15 at 18:49
  • @AAA JUnit only makes guarantees about what it controls, not about the logic you write. It can't control your implementation of a `@Test`. It gives you guidelines. – Sotirios Delimanolis Jan 09 '15 at 19:38
  • @SotiriosDelimanolis are you saying that the answer is wrong and that JUnit makes no guarantee about the order of the tests? If not, does the order fall under what JUnit controls or is that up the the logic I write? What does JUnit control regarding at-Rule and ExpectedException? As I understand it your comment is tautologous... – djechlin Jan 10 '15 at 00:16
  • 1
    @AAA JUnit (by default, you can tweak this) uses reflection to get your test methods. It use(d)s, for example, `Class#getMethods()` which returns a `Method[]` where the elements are not in any particular order. The JUnit, as these answers correctly state, does not specify the execution order of test method invocations. So, as a developer, if you add logic that depends on the order of invocations, you're doing that at your own risk. – Sotirios Delimanolis Jan 10 '15 at 01:33
  • The answer isn't wrong. JUnit guarantees no ordering of tests and if you write your own rule you could do something stupid, but the ExpectedException rule resets between each test being run – tddmonkey Jan 10 '15 at 14:20
2

JUnit tests are run in isolation. For each individual test the (default) test runner will create a new instance of the test class, and only call a single test-method (and the @Before and @After methods). So unless you create some static (or external) dependency that is influenced by order, the order of test execution is of no consequence to the result.

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
  • this might have been a testng thing but what about @BeforeSuite or equivalent? Those only seem applicable if multiple tests run in one class. – djechlin Jan 09 '15 at 17:23
  • I don't think this statement is accurate. I think it depends on how the unit test is run. I have seen multiple cases where tests fail because they change fields that are not reset in the `@Before`. If your assertion was correct, there would be no reason to use `@Before` since this could be done in the constructor. – John B Jan 09 '15 at 18:02
  • @JohnB you can check out the source of junit on github: each test is a new instance. Things like `@Before` are there for simplicity and readability, not out of necessity. And yes, in theory a test runner implementation could use a single instance for all tests, however exactly for reasons of test isolation, that would - generally - be a bad idea. – Mark Rotteveel Jan 10 '15 at 01:53
  • @AAA JUnit has `@BeforeClass` which is a static method, and therefor independent of the lifetime of the individual test instances. – Mark Rotteveel Jan 10 '15 at 10:20