When to use @RunWith and when @ExtendWith

My team and I have been working on a bunch of microservices using Spring boot. Since the services went through JUnit and Spring Boot upgrades (We're using now Spring Boot 2 and JUnit 5), different JUnit implemented by different devs, are now using different patterns with:

  • @ExtendWith
  • @RunWith

Today what's the difference between the two of them and do we really need them for our Unit Tests or are embedded in some new Spring Boot annotation?

59646 次浏览

@RunWith is an old annotation from JUnit 4 to use test runners. If you're using JUnit 5 (Jupiter), you should use @ExtendWith to use JUnit extensions.

The answer can be found in the documentation:

If you are using JUnit 4, don’t forget to add @RunWith(SpringRunner.class)to your test, otherwise the annotations will be ignored. If you are using JUnit 5, there’s no need to add the equivalent @ExtendWith(SpringExtension.class) as @SpringBootTest and the other @…Testannotations are already annotated with it

.

If you are using Junit version < 5, so you have to use @RunWith(SpringRunner.class) or @RunWith(MockitoJUnitRunner.class) etc.

If you are using Junit version = 5, so you have to use @ExtendWith(SpringExtension.class) or @ExtendWith(MockitoExtension.class) etc.

  1. SpringRunner
  2. MockitoJUnitRunner
  3. SpringExtension
  4. MockitoExtension

An important difference that was introduced with @ExtendWith is that it can receive an array of extensions allowing many of them to be used in the same test. Something like this, can be done

@ExtendWith({MockitoExtension.class, LogAsserterExtension.class})
class MyTest

With @RunWith back in JUnit 4, only one Runner class was allowed and you had problems when you want to use Mockito and Params on the test for example, because you couldn't use MockitoJUnitRunner and JUnitParamsRunner at the same time.