@Autowired 不应该在没有 @RunWith(SpringRunner.class) 的情况下工作,但可以 [英] @Autowired should not work without @RunWith(SpringRunner.class) but does
问题描述
这里是一个 java spring 数据存储层的单元测试类.我有一个 spring 数据存储库层,其中使用注解 @Autowired 注入 TestEntityManager 类型对象(属于 spring 数据包).自动装配工作无需添加@RunWith(SpringRunner.class) 注释!那么问题出在哪里呢?好吧,我认为在不向类中添加 @RunWith(SpringRunner.class) 注释的情况下,注入是不可能的:理论上,如果没有它,它应该无法工作.这怎么可能 ?有人有答案吗?
Here is a unit testing class for a java spring data repository layer. I have a spring data repository layer in which the annotation @Autowired is used to inject TestEntityManager type object (belongs to spring data package). The autowiring works whitout adding @RunWith(SpringRunner.class) annotation ! So what is the problem ? Well, I think that injection should not be possible whitout adding @RunWith(SpringRunner.class) annotation to the class : it should not work without it theorically. How is it possible ? Does someone have any answer ?
>>>>在此处查看 github 上完整的 Spring Boot 应用程序代码
- 其他人在 stackoverflow 中遇到了相反的问题:
这是我奇怪的代码块,它非常有效:
Here is my strange bloc of code that amazingly that works :
包 org.loiz.demo;
package 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);
}
}
也许这很正常,但我需要知道什么?我希望得到一些答案:)
Maybe it is normal, but what do i have to know ? I would appreciate some answer please :)
>>>>在此处查看 github 上完整的 Spring Boot 应用程序代码
推荐答案
@RunWith(SpringRunner.class)
用于 junit 4 测试.但在我们的例子中,使用的是 Junit 5.这就是我们可以在 pom.xml
文件中看到的内容(使用 junit.jupiter
工件证明了这一点).所以 @RunWith(SpringRunner.class)
对管理 spring 容器没有任何作用.它应该被替换为 @ExtendWith(SpringExtension.class)
.
@RunWith(SpringRunner.class)
is used for junit 4 test.
But in our case, it is Junit 5 that is used. That is what we can see reading at the pom.xml
file (using of junit.jupiter
artifact proves that).
So @RunWith(SpringRunner.class)
has no effects to manage spring container.
it should be replaced by @ExtendWith(SpringExtension.class)
.
然而:
@DataJpaTest
已经包含"了@ExtendWith(SpringExtension.class)
!!!所以我们在使用@DataJpaTest
时不需要添加@ExtendWith(SpringExtension.class)
.@DataJpaTest
将允许测试 spring 数据存储库层,但也将保证 spring 依赖注入.也就是说,粗略地说,您可以将 @Autowired
注释用于注释为 @DataJpaTest
(spring 数据存储库层)的类.
@DataJpaTest
already "contains" @ExtendWith(SpringExtension.class)
!!!
So we don't need to add @ExtendWith(SpringExtension.class)
when @DataJpaTest
is used.
@DataJpaTest
will allow to test spring data repository layer but will also guarantee spring dependency injection.
That is to say, and roughly speeking, you can use @Autowired
annotation for a class which is annotated @DataJpaTest
(a spring data repository layer).
这篇关于@Autowired 不应该在没有 @RunWith(SpringRunner.class) 的情况下工作,但可以的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!