The explanation for how it works:
JUnit wraps your test method in a Statement object so statement and Execute()
runs your test. Then instead of calling statement.Execute()
directly to run your test, JUnit passes the Statement to a TestRule with the @Rule
annotation. The TestRule's "apply" function returns a new Statement given the Statement with your test. The new Statement's Execute()
method can call the test Statement's execute method (or not, or call it multiple times), and do whatever it wants before and after
.
Now, JUnit has a new Statement that does more than just run the test, and it can again pass that to any more rules before finally calling Execute.