【问题标题】:@Autowired should not work without @RunWith(SpringRunner.class) but does@Autowired 不应该在没有 @RunWith(SpringRunner.class) 的情况下工作,但可以
【发布时间】:2020-12-17 20:44:19
【问题描述】:

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

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

  • 其他人在 stackoverflow 中遇到了相反的问题

Someone else have had the opposite problem : see link 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

【问题讨论】:

    标签: spring spring-boot unit-testing dependency-injection repository


    【解决方案1】:

    @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 依赖注入。 也就是说,粗略地说,您可以将@Autowired注解用于注解@DataJpaTest(spring数据存储层)的类。

    【讨论】:

      【解决方案2】:

      从导入 junit.jupiter 我可以看到你正在使用 junit-5@RunWith 属于 junit-4,并且作为参考 @ExtendWith 不是用于 junit-5 测试的命令,如果你想使用特定的跑步者你仍然需要@ExtendsWith,但@DataJpaTest本身是用@ExtendsWith注释的,你不需要明确地这样做

      在 JUnit 5 中,@RunWith 注释已被更强大的 @ExtendWith 注释所取代。

      要使用此类,只需使用 @RunWith(SpringJUnit4ClassRunner.class)@RunWith(SpringRunner.class) 注释基于 JUnit 4 的测试类。

      【讨论】:

      • 非常感谢“DeadPool”?
      • 好吧,如果您想使用特定的跑步者,您仍然需要 @ExtendsWith 但是 因为 @DataJpaTest 本身带有 @ExtendsWith 注释,您不需要这样做这是明确的。
      • 感谢@M.Deinum 更新了答案,再次感谢您一直帮助我学习新事物
      • 致 M. Deinum > 你是对的。我为自己的问题写了一个答案,以便一些匿名网络查看者给出一些明确的答案。
      猜你喜欢
      • 1970-01-01
      • 2021-04-14
      • 1970-01-01
      • 2014-02-24
      • 2019-01-14
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      • 2018-01-10
      相关资源
      最近更新 更多