@Autowired 在没有 @RunWith(SpringRunner.class) 的情况下不应该工作,但是可以

@Autowired should not work without @RunWith(SpringRunner.class) but does

这是 class java spring 数据存储库层的单元测试。 我有一个 spring 数据存储层,其中注解 @Autowired 用于注入 TestEntityManager 类型对象(属于 spring 数据包)。 自动装配无需添加 @RunWith(SpringRunner.class) 注释即可工作! 那么问题是什么?好吧,我认为如果不向 class 添加 @RunWith(SpringRunner.class) 注释就不可能进行注入:从理论上讲,如果没有它,它就无法工作。 这怎么可能 ?有人有答案吗?

>>>> view complete spring boot app code on github available here

这是我奇怪的代码块,它非常有效:

包 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);
        
    }

}

也许这很正常,但我需要知道什么? 请给我一些答复:)

>>>> view complete spring boot app code on github available here

从进口 junit.jupiter 我可以看到你正在使用 junit-5, were @RunWith belongs to junit-4, and for reference @ExtendWith is not mandataroy for junit-5 test and if you want to use a specific runner you still require the @ExtendsWith but as @DataJpaTest 本身用 @ExtendsWith 注释你不需要明确地这样做

In JUnit 5, the @RunWith annotation has been replaced by the more powerful @ExtendWith annotation.

To use this class, simply annotate a JUnit 4 based test class with @RunWith(SpringJUnit4ClassRunner.class) or @RunWith(SpringRunner.class).

@RunWith(SpringRunner.class) 用于 junit 4 测试。 但在我们的例子中,使用的是 Junit 5。这就是我们在 pom.xml 文件中看到的内容(使用 junit.jupiter 工件证明了这一点)。 所以 @RunWith(SpringRunner.class) 对管理 spring 容器没有影响。 它应该被替换为 @ExtendWith(SpringExtension.class).

但是:

@DataJpaTest 已经“包含”@ExtendWith(SpringExtension.class) !!! 所以我们不需要在使用@DataJpaTest的时候加上@ExtendWith(SpringExtension.class)@DataJpaTest 将允许测试 spring 数据存储层,但也会保证 spring 依赖注入。 也就是说,粗略地说,您可以对 class 使用 @Autowired 注释,该 class 被注释 @DataJpaTest (spring 数据存储层)。