Должны ли мы написать модульный тест и тест интеграции для уровня репозитория в Spring Boot?

#java #spring #unit-testing #spring-boot #spring-boot-test

#java #spring #модульное тестирование #spring-boot #spring-boot-test

Вопрос:

У меня есть куча вопросов, касающихся Spring Boot уровня репозитория.

Мои вопросы:

  1. Должны ли мы вообще писать модульный тест и тест интеграции для уровня репозитория в Spring Boot , у которого нет никакого пользовательского кода или запроса?
  2. Каков наилучший подход к написанию интеграционного теста для уровня репозитория в Spring Boot ? Я перечислил оба подхода ниже. Какой из обоих подходов лучше. Есть ли какая-либо лучшая практика, в которой я должен следовать одному за другим?
  3. Если ответ на мой приведенный выше вопрос # 1 положительный, то как мне написать модульный тест для уровня репозитория в Spring Boot ?

CurrencyRepository.java

 @Repository
public interface CurrencyRepository extends CrudRepository<Currency, String> {

}
  

Поскольку при этом используется встроенная база данных H2, это интеграционный тест, а не модульный тест. Правильно ли я понимаю?

CurrencyRepositoryIntegrationTest.java (Подход 1)

 @RunWith(SpringRunner.class)
@DataJpaTest
public class CurrencyRepositoryIntegrationTest {

    @Autowired
    private TestEntityManager entityManager;
    @Autowired
    private CurrencyRepository repository;

    @Test
    public void testFindByName() {
        entityManager.persist(new Currency("USD", "United States Dollar", 2L));
        Optional<Currency> c = repository.findById("USD");
        assertEquals("United States Dollar", c.get().getCcyNm());
    }

}
  

CurrencyRepositoryIntegrationTest2.java (Подход 2)

 @RunWith(SpringRunner.class)
@SpringBootTest(classes = DemoApplication.class)
public class CurrencyRepositoryIntegrationTest2 {

    @Autowired
    private CurrencyRepository repository;

    @Test
    public void testFindByName() {
        repository.save(new Currency("USD", "United States Dollar", 2L));
        Optional<Currency> c = repository.findById("USD");
        assertEquals("United States Dollar", c.get().getCcyNm());
    }

}
  

Комментарии:

1. Я лично не вижу причин для модульного тестирования конкретного класса, который я не кодировал, но я реализую интеграционное тестирование для моего уровня репозитория, чтобы убедиться, что методы запроса дают ожидаемые результаты.

Ответ №1:

Для интеграционного теста есть старая поговорка «Не издевайся над тем, чем ты не владеешь». Смотрите, например https://markhneedham.com/blog/2009/12/13/tdd-only-mock-types-you-own / и https://8thlight.com/blog/eric-smith/2011/10/27/thats-not-yours.html

Тест JUnit, который вы бы написали, будет имитировать базовый EntityManger, чтобы проверить, правильно ли реализован spring. Мы надеемся, что этот тест у разработчиков spring уже есть, поэтому я бы не стал его повторять.

Что касается интеграционного теста, я полагаю, вам все равно, как и использует ли репозиторий EntityManager под ним. Вы просто хотите посмотреть, правильно ли это поведение. Итак, второй подход подходит лучше.