英文:
when you run integration Test, no data will be saved in the database
问题
以下是您提供的内容的翻译部分:
我正在尝试编写服务层的集成测试。检查从数据库中读取所有字段的方法。
实体类
@Getter@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "users", schema = "main")
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private Long id;
private String name;
}
服务
@RequiredArgsConstructor
@Service
@Transactional
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Override
public UserEntity create(UserEntity object) {
return userRepository.save(object);
}
@Override
public UserEntity get(Long id) {
return userRepository.findById(id)
.orElseThrow(() -> new NotFoundException(USER_NOT_FOUND));
}
}
对于测试,我使用了h2数据库,设置是标准的。
spring:
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS main
driverClassName: org.h2.Driver
username: sa
password: password
服务层的集成测试
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserIntTest {
@Autowired
private UserService userService;
@Test
@Sql({"/getUsers_shouldOk.sql"})
@Transactional
public void getUsers_shouldOk() {
var result = userService.getAll();
// 我也尝试过这种方式
//var result = userRepository.findAll();
assertThat(result, notNullValue());
assertThat(result.size(), is(3));
}
}
文件 getUsers_shouldOk.sql
INSERT INTO `user` (`id`, `name`) VALUES (1, 'user-01');
INSERT INTO `user` (`id`, `name`) VALUES (2, 'user-02');
INSERT INTO `user` (`id`, `name`) VALUES (3, 'user-03');
我在此方法上使用了 @Sql
注解,向数据库添加了三个条目。但是当从数据库中读取数据时,我得到一个空列表。getUsers_shouldOk.sql
文件位于资源文件夹中。在运行此文件的测试时没有错误。为什么我无法从数据库中读取数据?
似乎问题在于我使用了模式,我在最初的问题中没有指定它,现在我已经更正了问题。
我在代码中还有一个错误,在 getUsers_shouldOk.sql
文件中我也忘记指定了模式。但是我不明白为什么我没有收到错误。如果我尝试在终端中访问用户表,我会收到表不存在的错误,但只有这样才能工作
main.users
但是当我将模式添加到 getUsers_shouldOk.sql
文件中时,当我运行测试时,现在我收到了错误
Failed to execute SQL script statement #1 of class path resource [getManufactures_shouldOk.sql]: INSERT INTO `main.users` (`id`, `name`) VALUES (1, 'user-01'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "main.users" not found
希望这可以帮助您理解问题和解决方案。
英文:
I'm trying to write an integration test of the service layer. The method of checking the reading of all fields from the database.
Entity class
@Getter@Setter
@AllArgsConstructor
@NoArgsConstructor
@Entity
@Table(name = "users", schema = "main")
public class UserEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Access(AccessType.PROPERTY)
private Long id;
private String name;
}
Service
@RequiredArgsConstructor
@Service
@Transactional
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;
@Override
public UserEntity create(UserEntity object) {
return UserRepository.save(object);
}
@Override
public UserEntity get(Long id) {
return UserRepository.findById(id)
.orElseThrow(() -> new NotFoundException(USER_NOT_FOUND));
}
}
For tests, I use the h2 database, the settings are standard
spring:
datasource:
url: jdbc:h2:mem:testdb;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS main
driverClassName: org.h2.Driver
username: sa
password: password
Integration tests for the service layer
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class UserIntTest {
@Autowired
private UserService UserService;
@Test
@Sql({"/getUsers_shouldOk.sql"})
@Transactional
public void getUsers_shouldOk() {
var result = userService.getAll();
// I've tried that too
//var result = userRepository.findAll();
assertThat(result, notNullValue());
assertThat(result.size(), is(3));
}
}
File getUsers_shouldOk.sql
INSERT INTO `user` (`id`, `name`) VALUES (1, 'user-01');
INSERT INTO `user` (`id`, `name`) VALUES (2, 'user-02');
INSERT INTO `user` (`id`, `name`) VALUES (3, 'user-03');
I add three entries to the database using the @Sql annotation on this method. But when reading data from the database, I get an empty list. The sql file getUsers_shouldOk.sql is located in the resources folder. There are no errors when running the test on this file. Why can't I read the data from the database?
It seems that the problem is that I use a scheme, I did not specify it in the original question, now I have corrected the question.
I also had an error in my code, in the getUsers_shouldOk.sql file I also forgot to specify the schema. But I don't understand why I didn't get the error. If I try to access the users table in the terminal, I get an error that there is no such table, but it only works like this
main.users
But when I added the schema to the getUsers_shouldOk.sql file, when I run the test, I now get an error
Failed to execute SQL script statement #1 of class path resource [getManufactures_shouldOk.sql]: INSERT INTO `main.users` (`id`, `name`) VALUES (1, 'user-01'); nested exception is org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "main.users" not found
答案1
得分: 1
@Rollback(false) 或 @Commit,取决于您的Spring版本。
英文:
@Rollback(false) or @Commit depending on your Spring version.
答案2
得分: 1
First, add instructio to create database schema, since you are not doing it by yourself (but it should be by default i think)
首先,添加创建数据库模式的指令,因为您不会自己创建(但我认为默认情况下应该是这样的)
spring.jpa.hibernate.ddl-auto=create-drop (convert to yaml if needed)
spring.jpa.hibernate.ddl-auto=create-drop(如有需要,请转换为yaml格式)
next, decide if your table is going to be users
as here
接下来,决定您的表是否要像这样命名为`users`
@Table(name = "users", schema = "main")
@Table(name = "users", schema = "main")
or user
as here
或者像这样命名为`user`
INSERT INTO user
(id
, name
) VALUES (1, 'user-01');
INSERT INTO `user` (`id`, `name`) VALUES (1, 'user-01');
and last thing fyi, @Transactional
method in test will end up with rolled back transaction (which is good actually as long as you dont want to test some post transaction logic). Reading anything from the db after test will not work.
最后提醒一下,测试中的`@Transactional`方法将以回滚的方式结束事务(实际上这是好事,只要您不想测试一些事务后的逻辑)。测试后从数据库读取任何内容都将无法正常工作。
英文:
First, add instructio to create database schema, since you are not doing it by yourself (but it should be by default i think)
spring.jpa.hibernate.ddl-auto=create-drop (convert to yaml if needed)
next, decide if your table is going to be users
as here
@Table(name = "users", schema = "main")
or user
as here
INSERT INTO `user` (`id`, `name`) VALUES (1, 'user-01');
and last thing fyi, @Transactional
method in test will end up with rolled back transaction (which is good actually as long as you dont want to test some post transaction logic). Reading anything from the db after test will not work.
答案3
得分: 0
你可以使用H2数据库,它是一个内存数据库,在Spring Boot项目的resources文件夹下创建schema.sql文件,并添加创建表的语句。
创建import.sql并添加SQL查询语句(创建、更新、删除)。
在JUnit中从表中提取给定的数据。
您可以参考:https://www.baeldung.com/spring-jpa-test-in-memory-database
英文:
You can use H2 DB. which is in-memory database. in spring boot projects under resources folder create schema.sql and add create table statements.
create import.sql add sql queries (create,update,delete).
In Junit fetch data from details give in table.
You can refer: https://www.baeldung.com/spring-jpa-test-in-memory-database
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论