@Autowired не должен работать без @RunWith(SpringRunner.class), но работает

Вот класс модульного тестирования для уровня репозитория данных java spring. У меня есть уровень репозитория данных Spring, в котором аннотация @Autowired используется для внедрения объекта типа TestEntityManager (принадлежит пакету данных Spring). Автопроводка работает без добавления аннотации @RunWith(SpringRunner.class)! Так в чем проблема ? Ну, я думаю, что инъекция не должна быть возможной без добавления аннотации @RunWith(SpringRunner.class) к классу: теоретически она не должна работать без нее. Как это возможно ? У кого-нибудь есть ответ?

>>>> Посмотреть полный код приложения Spring Boot на github можно здесь

  • У кого-то была противоположная проблема в stackoverflow:

У кого-то была обратная проблема: см. ссылку здесь

Вот мой странный блок кода, который удивительно работает:

пакет org.loiz.demo;

import org.assertj.core.api.BDDAssertions;
import org.junit.Assert;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Test ;
import org.junit.jupiter.api.TestMethodOrder;
import org.junit.jupiter.api.Order ;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;

import demo.LoizBootSpringDemoApplication;
import demo.crepository.UserRepositoryInterface;
import demo.dmodel.User;
import demo.helper.helperUtils;

//Test de la couche de persistence
//@RunWith(SpringRunner.class)
@DataJpaTest
@ContextConfiguration(classes = { LoizBootSpringDemoApplication.class})
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@SuppressWarnings("unused")
public class LoizPersistenceTest 
{
    
    @Autowired
    private TestEntityManager testEntityManager;

    @Autowired
    private UserRepositoryInterface repository; 

    private static Long idStub ;
    
    @Test
    @Order(1)
    @Rollback(false)
    @DisplayName("Test de sauvegarde d\'un user \"prenom21 Nom21\"")    
    public void saveShouldMapCorrectly() throws Exception {
        
        User userStub = new User("prenom21", "Nom21");                       
        
        User UserSaved = this.testEntityManager.persistFlushFind(userStub);
        
        BDDAssertions.then(UserSaved.getId()).isNotNull();                    
        idStub = UserSaved.getId() ;
        
        User UserRead = this.testEntityManager.find(User.class, idStub) ;       
        
        BDDAssertions.then(UserSaved.getFirstName()).isNotBlank();
        BDDAssertions.then(UserSaved.getFirstName()).isEqualToIgnoringCase("prenom21");
        

        BDDAssertions.then(UserSaved.getLastName()).isEqualToIgnoringCase("Nom21");
        BDDAssertions.then(UserSaved.getLastName()).isNotBlank();
    }

    @Test
    @Order(2) 
    @DisplayName("Test d'existence du user \"prenom21 Nom21\"") 
    public void readShouldMapCorrectly() throws Exception {
        User userStub = new User(idStub, "prenom21", "Nom21");          
        User userFetched  = this.testEntityManager.find(User.class, idStub) ;
        
        String sUserStub = userStub.toString() ;        
        String sUserFetched = userFetched.toString() ;      
        
        
        boolean bolSameObject = userStub.equals(userFetched) ;
        
        boolean bolAttrEgalEgal = sUserStub == sUserFetched ;       
        
        boolean bolStringEqual = sUserStub.equals(sUserFetched) ;           
        
        boolean bBeanUtil = helperUtils.haveSamePropertyValues (User.class,userStub,userFetched) ;
        
                
        Assert.assertTrue(bBeanUtil);
        
    }

}

Может быть, это нормально, но что я должен знать? Буду признателен за ответ, пожалуйста :)

>>>> Посмотреть полный код приложения Spring Boot на github можно здесь

4
0
972
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Из импорта junit.jupiter я вижу, что вы используете junit-5 , где @RunWith принадлежит junit-4 , и для справки @ExtendWith не является мандатарием для теста junit-5, и если вы хотите использовать конкретный бегун, вы все равно требуется @ExtendsWith, но поскольку @DataJpaTest сам по себе аннотирован @ExtendsWith, вам не нужно делать это явно

В JUnit 5 аннотация @RunWith была заменена более мощной аннотацией @ExtendWith.

Чтобы использовать этот класс, просто аннотируйте тестовый класс на основе JUnit 4 с помощью @RunWith(SpringJUnit4ClassRunner.class) или @RunWith(SpringRunner.class).

Большое спасибо "Дэдпул" 👍

Jimmy Maghrebien 18.12.2020 00:10

Что ж, если вы хотите использовать конкретный бегун, вам все равно потребуется @ExtendsWith, но поскольку @DataJpaTest само по себе аннотировано @ExtendsWith, вам не нужно делать это явно.

M. Deinum 18.12.2020 10:39

Спасибо @M.Deinum обновил ответ и еще раз спасибо за то, что всегда помогаете мне узнавать новое.

Ryuzaki L 18.12.2020 16:00

М. Дейнуму > Вы правы. Я пишу себе ответ на свой вопрос, чтобы какой-нибудь анонимный веб-просмотрщик дал четкий ответ.

Jimmy Maghrebien 18.12.2020 16:03
Ответ принят как подходящий

@RunWith(SpringRunner.class) используется для теста Junit 4. Но в нашем случае используется именно Junit 5. Это то, что мы видим, читая файл pom.xml (использование артефакта junit.jupiter тому доказательство). Таким образом, @RunWith(SpringRunner.class) не влияет на управление пружинным контейнером. его следует заменить на @ExtendWith(SpringExtension.class).

ОДНАКО :

@DataJpaTest уже "содержит" @ExtendWith(SpringExtension.class) !!! Поэтому нам не нужно добавлять @ExtendWith(SpringExtension.class), когда используется @DataJpaTest. @DataJpaTest позволит протестировать слой репозитория данных Spring, но также гарантирует внедрение зависимостей Spring. То есть, грубо говоря, вы можете использовать аннотацию @Autowired для класса, который аннотирован @DataJpaTest (уровень репозитория данных Spring).

Другие вопросы по теме