Junit 5 с Spring Boot: когда использовать @Extend с Spring или Mockito? - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть следующий абстрактный класс модульных тестов , который расширяют все мои классы модульных тестов:

@ExtendWith(SpringExtension.class)
//@ExtendWith(MockitoExtension.class)
@SpringBootTest(
    classes = PokerApplication.class,
    webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT
)
public abstract class AbstractUnitTests {

    @MockBean
    public RoundService roundService;

    @MockBean
    public RoundRepository roundRepository;
}

В чем разница между использованием @ExtendWith(SpringExtension.class) или @ExtendWith(MockitoExtension.class)?

Я спрашиваю, так как использование одной из аннотаций, кажется, не имеет значения, и обе работают соответственно в моем коде - позволяя мне использовать Junit5. Так почему же работают оба?

Класс теста бетона:

    @DisplayName("Test RoundService")
    public class RoundsServiceTest extends AbstractUnitTests {

        private static String STUB_USER_ID = "user3";

        // class under test
        @InjectMocks
        RoundService roundService;

        private Round round;

        private ObjectId objectId;

        @BeforeEach //note this replaces the junit 4 @Before
        public void setUp() {

            initMocks(this);
            round = Mocks.round();
            objectId = Mocks.objectId();
        }

        @DisplayName("Test RoundService.getAllRoundsByUserId()")
        @Test
        public void shouldGetRoundsByUserId() {

            // setup
            given(roundRepository.findByUserId(anyString())).willReturn(Collections.singletonList(round));

            // call method under test
            List<Round> rounds = roundService.getRoundsByUserId(STUB_USER_ID);

            // asserts
            assertNotNull(rounds);
            assertEquals(1, rounds.size());
            assertEquals("user3", rounds.get(0).userId());
        }
}

Соответствующий раздел Build.gradle :

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
    implementation 'org.springframework.boot:spring-boot-starter-data-mongodb'
    compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '2.2.2.RELEASE'

    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
    implementation 'junit:junit:4.12'
}

test {
    useJUnitPlatform()
}

1 Ответ

1 голос
/ 26 апреля 2020

Что такое расширение Junit

Цель расширений Junit 5 - расширить поведение тестовых классов или методов

source

Продолжение чтения Модель расширения Junit 5 & @ExtendWith аннотация: здесь

SpringExtension

SpringExtension интегрирует Spring TestContext Framework в модель программирования JUnit 5 Jupiter.

public class SpringExtension
extends Object
implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor, BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver{..}

MockitoExtension

Это расширение JUnit Jupiter эквивалент нашего JUnit4 MockitoJUnitRunner

public class MockitoExtension
extends java.lang.Object
implements BeforeEachCallback, AfterEachCallback, ParameterResolver{..}

Как видно, SpringExtension реализует намного больше расширений, чем MockitoExtension.

Также @SpringBootTest мета-аннотируется с помощью @ExtendWith(SpringExtension.class), и это означает, что каждый раз, когда ваши тесты расширяются с помощью SpringExtension. @MockBean - это аннотация каркаса Spring, используемая вместе с @ExtendWith(SpringExtension.class)

Чтобы увидеть разницу, попробуйте следующее

ExtendWith только MockitoExtension

@ExtendWith(MockitoExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

    @Test
    void test() {
        assertNotNull(service); // Test will fail
    }

}

ExtendWith только SpringExtension

@ExtendWith(SpringExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

    @Test
    void test() {
        assertNotNull(service); // Test succeeds
    }

}

ExtendWith с обоими SpringExtension и MockitoExtension

@ExtendWith(MockitoExtension.class)
@ExtendWith(SpringExtension.class)
class TestServiceTest {

    @MockBean
    TestService service;

    @Test
    void test() {
        assertNotNull(service); // Test succeeds
    }

}

Оба работают в вашем случае, потому что @SpringBootTest аннотации для тестового класса, как объяснено.

Чтобы ответить на вопрос: когда использовать @ExtendWith Spring или Mockito? ,

Когда для теста требуется контекст Spring Test (для автоматической передачи компонента / использования @MockBean) вместе с моделью программирования JUnit 5 Jupiter, используйте @ExtendWith(SpringExtension.class). Это будет поддерживать аннотации Mockito также через TestExecutionListeners.

Когда тест использует Mockito и нуждается в поддержке модели программирования Jupit 5 JUnit, используйте @ExtendWith(MockitoExtension.class)

Надеюсь, это поможет

...