@DataJpaTest обновляет фактические данные в случае MySQL, но работает нормально с H2 - PullRequest
0 голосов
/ 02 мая 2020

Я изучаю @DataJpaTest, мой тестовый пример, как показано ниже

import com.demo.mockito.entity.StudentEntity;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
class StudentRepositoryTest {
    @Autowired
    private StudentRepository studentRepository;
    @Test
    public void findAll() {
        StudentEntity student1 = new StudentEntity("shrikant", new Date());
        studentRepository.save(student1);
        List<StudentEntity> entityList = studentRepository.findAll();
        assertEquals(1, entityList.size());
    }
}

, дает ошибку

expected: <1> but was: <33>
Expected :1
Actual   :33
<Click to see difference>

, потому что сейчас в БД 33 записи, и с при каждом сохранении тестового случая оно увеличивается.

src / main / test / application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/student_db?jdbcCompliantTruncation=false&sessionVariables=sql_mode='NO_ENGINE_SUBSTITUTION'&useSSL=false&useServerPrepStmts=false&rewriteBatchedStatements=true&useUnicode=true&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
spring.jpa.generate-ddl=true
spring.jpa.database.schema=student_db
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true

build.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version '2.2.6.RELEASE'
    id 'io.spring.dependency-management' version '1.0.9.RELEASE'
}
group 'com.demo.mockito'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    compile 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testRuntime('org.junit.jupiter:junit-jupiter-engine:5.2.0')
    runtime 'mysql:mysql-connector-java'
    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}
test {
    useJUnitPlatform()
}

, если вместо этого я использую h2, он дает правильный результат beucase каждый раз, когда воссоздает новый экземпляр без данных.

это предполагаемое поведение? или я делаю что-то не так, это стандарт h2 в случае тестирования базы данных. но я не хочу настраивать другую базу данных в моем приложении, когда я собираюсь протестировать только MySQL.

1 Ответ

2 голосов
/ 02 мая 2020

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

Вы сами ответили на свой вопрос.
Bu по умолчанию при каждом запуске контейнера Spring Boot (что происходит, когда вы определяете тест с @SpringBootTest или аннотацией тестовой нарезки @DataJpaTest), новый экземпляр базы данных создается, когда вы используете внутреннюю БД, такую ​​как H2 (это поведение по умолчанию для H2, которое вы можете изменить), а когда вы используете MySQL, Spring Boot по умолчанию не использует эту стратегию. Он не изменяет содержимое БД.
Официальный do c действительно заявляет :

Spring Boot выбирает значение по умолчанию для вас на основе того, считает ли он вашу базу данных встроен По умолчанию создается-отбрасывание, если не обнаружен менеджер схемы или его нет во всех других случаях.

О программе:

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

Для модульных тестов вы хотите использовать DB в оперативной памяти как H2, потому что это прямое и не требует длительной / сложной настройки (это заполнение / очистка состояния БД).
Для интеграционных тестов вы хотите использовать целевую БД (здесь MySQL), потому что вы хотите написать тесты, наиболее близкие к поведению вашего приложения. Чтобы достичь этого, вам нужно использовать указанную c DB (тестовую базу данных), вам также нужно заполнить данные приборов для тестов и, наконец, вы должны очистить данные, чтобы сделать тесты воспроизводимыми.

Оба вида тестов являются взаимодополняющими.

...