Вот класс модульного тестирования для уровня репозитория данных java spring. У меня есть уровень репозитория данных Spring, в котором аннотация @Autowired используется для внедрения объекта типа TestEntityManager (принадлежит пакету данных Spring). Автопроводка работает без добавления аннотации @RunWith(SpringRunner.class)! Так в чем проблема ? Ну, я думаю, что инъекция не должна быть возможной без добавления аннотации @RunWith(SpringRunner.class) к классу: теоретически она не должна работать без нее. Как это возможно ? У кого-нибудь есть ответ?
>>>> Посмотреть полный код приложения Spring Boot на github можно здесь
У кого-то была обратная проблема: см. ссылку здесь
Вот мой странный блок кода, который удивительно работает:
пакет 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 можно здесь
Из импорта 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)
.
Что ж, если вы хотите использовать конкретный бегун, вам все равно потребуется @ExtendsWith
, но поскольку @DataJpaTest
само по себе аннотировано @ExtendsWith
, вам не нужно делать это явно.
Спасибо @M.Deinum обновил ответ и еще раз спасибо за то, что всегда помогаете мне узнавать новое.
М. Дейнуму > Вы правы. Я пишу себе ответ на свой вопрос, чтобы какой-нибудь анонимный веб-просмотрщик дал четкий ответ.
@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).
Большое спасибо "Дэдпул" 👍