@DataJpaTest 在 MySQL 的情况下更新实际数据但与 H2 一起工作正常
@DataJpaTest updating actual data in case of MySQL but working fine with H2
我正在学习@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.属性
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,它会在每次重新创建没有数据的新实例时给出正确的结果。
这是有意为之的行为吗?还是我做错了什么,
在数据库测试的情况下是 h2 标准。
但是当我只想测试 MySQL 时,我不想在我的应用程序中配置另一个数据库。
if i use h2 instead, it gives correct result because every time it
recreates a new instance with no data.
你自己回答了你的问题。
Bu 默认情况下,在每个 Spring 引导容器启动时(当您使用 @SpringBootTest
或测试切片 @DataJpaTest
注释定义测试时发生),当您使用 in 时创建一个新的数据库实例-内存数据库,例如 H2(这是 H2 的默认行为,您可以更改),而当您使用 MySQL、Spring 时,默认情况下引导不使用该策略。它不会更改数据库内容。
The official doc states indeed :
Spring Boot chooses a default value for you based on whether it thinks
your database is embedded. It defaults to create-drop if no schema
manager has been detected or none in all other cases.
关于:
but I don't want to configure another database in my application when
my intention is to test MySQL only.
对于单元测试,您希望使用内存中的数据库作为 H2,因为它是直接的并且不需要 long/complex 设置(即 populating/cleaning 数据库状态)。
对于集成测试,您希望使用目标数据库(此处 MySQL),因为您希望编写的测试最接近您的应用程序行为。
为此,您必须使用特定的数据库(测试数据库),还必须为测试填充夹具数据,最后必须清理数据以使测试可重现。
这两种测试是相辅相成的。
我正在学习@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.属性
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,它会在每次重新创建没有数据的新实例时给出正确的结果。
这是有意为之的行为吗?还是我做错了什么, 在数据库测试的情况下是 h2 标准。 但是当我只想测试 MySQL 时,我不想在我的应用程序中配置另一个数据库。
if i use h2 instead, it gives correct result because every time it recreates a new instance with no data.
你自己回答了你的问题。
Bu 默认情况下,在每个 Spring 引导容器启动时(当您使用 @SpringBootTest
或测试切片 @DataJpaTest
注释定义测试时发生),当您使用 in 时创建一个新的数据库实例-内存数据库,例如 H2(这是 H2 的默认行为,您可以更改),而当您使用 MySQL、Spring 时,默认情况下引导不使用该策略。它不会更改数据库内容。
The official doc states indeed :
Spring Boot chooses a default value for you based on whether it thinks your database is embedded. It defaults to create-drop if no schema manager has been detected or none in all other cases.
关于:
but I don't want to configure another database in my application when my intention is to test MySQL only.
对于单元测试,您希望使用内存中的数据库作为 H2,因为它是直接的并且不需要 long/complex 设置(即 populating/cleaning 数据库状态)。
对于集成测试,您希望使用目标数据库(此处 MySQL),因为您希望编写的测试最接近您的应用程序行为。
为此,您必须使用特定的数据库(测试数据库),还必须为测试填充夹具数据,最后必须清理数据以使测试可重现。
这两种测试是相辅相成的。