当您运行集成测试时,不会将任何数据保存在数据库中。

huangapple go评论57阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年6月9日 00:20:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76433901.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定