1

我正在开发 Spring Boot 并尝试使用 H2 数据库(在内存中)进行单元测试。我的 Spring Data 存储库实现不起作用,我需要帮助来调试它。

我已将我的项目(不使用原始项目)简化为以下示例以隔离和演示问题。该项目可以在GitHub中找到。

Eclipse项目结构:

项目结构

pom.xml:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
        <version>2.3.0.1</version>
    </dependency>
    <dependency>
        <groupId>javax.activation</groupId>
        <artifactId>activation</artifactId>
        <version>1.1.1</version>
    </dependency>
    <dependency>
        <groupId>javax.transaction</groupId>
        <artifactId>jta</artifactId>
        <version>1.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.apache.maven</groupId>
        <artifactId>maven-model</artifactId>
        <version>3.5.4</version>
    </dependency>
    <dependency>
        <groupId>org.modelmapper</groupId>
        <artifactId>modelmapper</artifactId>
        <version>2.2.0</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <executable>true</executable>
                <skipTests>true</skipTests>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>repackage</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

<repositories>
    <repository>
        <id>spring-releases</id>
        <url>https://repo.spring.io/libs-release</url>
    </repository>
</repositories>
<pluginRepositories>
    <pluginRepository>
        <id>spring-releases</id>
        <url>https://repo.spring.io/libs-release</url>
    </pluginRepository>
</pluginRepositories>

应用程序属性:

debug=true

logging.level.root=WARN
logging.level.org.foo=WARN
logging.level.org.springframework=WARN

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:test_database;DB_CLOSE_DELAY=-1
spring.datasource.username=sa
spring.datasource.password=sa

spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console

主要配置类:

@SpringBootApplication
@Configuration
@PropertySource("classpath:application.properties")
@EnableJpaRepositories(basePackages = "org.foo.repositories")
@EntityScan("org.foo.entities")
@EnableTransactionManagement
public class Application {

    Logger logger = LoggerFactory.getLogger(Application.class);

    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(Application.class);
        SpringApplication.run(Application.class, args);
        logger.info("Application started");
    }

    @Bean
    public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
        return args -> {

            logger.trace("Let's inspect the beans provided by Spring Boot:");
            String[] beanNames = ctx.getBeanDefinitionNames();
            Arrays.sort(beanNames);
            for (String beanName : beanNames) {
                logger.trace(beanName);
            }
        };
    }
}

学生实体类:

package org.foo.entities;

import javax.persistence.Entity;
import javax.persistence.Id;
import lombok.Data;

@Entity
@Data
public class Student {

    @Id
    private long id;

    private String first_name;

    private String last_name;

}

StudentRepository 类:

@Repository
public interface StudentRepository extends JpaRepository<Student, Long> {
    @Override
    List<Student> findAll();
}

StudentRepositoryTester 类:

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
@ContextConfiguration(classes = { org.foo.Application.class }, loader = AnnotationConfigContextLoader.class)
public class StudentRepositoryTester {

    Logger logger = LoggerFactory.getLogger(StudentRepositoryTester.class);

    @Autowired
    private StudentRepository studentRepository;

    @Test
    public void findAllTester() {
        Iterable<Student> students = studentRepository.findAll();
        for(Student student: students) {
            logger.info(student.toString());
        }
        long size = StreamSupport.stream(students.spliterator(), false).count();
        assertTrue(students != null && size == 3);
    }

}

数据.sql:

USE `test_database`;

INSERT INTO `students` (`id`,`first_name`,`last_name`) VALUES (1,'First1','Last1');
INSERT INTO `students` (`id`,`first_name`,`last_name`) VALUES (2,'First2','Last2');
INSERT INTO `students` (`id`,`first_name`,`last_name`) VALUES (3,'First3','Last3');

架构.sql:

DROP ALL OBJECTS; 

CREATE SCHEMA `test_database`;
USE `test_database`;

CREATE TABLE `students` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `first_name` varchar(45) NOT NULL,
  `last_name` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
);

我可以在控制台日志中看到 H2 已填充,因为我可以看到 data.sql 中的语句已执行。我在日志中没有看到任何可疑之处。

具体问题:

  1. 运行 StudentRepositoryTester 测试类,我看到(在断言语句上有断点)没有返回任何实体。我不明白为什么。也许我错过了 Spring Boot 配置注释中的某些内容?

  2. 我试图检查断点中的数据库内容,但我找不到探索 H2 数据库的方法。我按照本教程打开 H2 的 Web 浏览器应用程序,但在 localhost:8080 中没有提供任何服务。难道我做错了什么?或者,是否有另一种方法来调试 H2 数据库(在内存中)中发生的事情?

请注意,相应的 Eclipse 项目已上传到GitHub以方便讨论。

4

2 回答 2

4

打开 Hibernate 执行的 SQL 语句的日志记录(在 application.properties 中):

logging.level.org.hibernate.SQL=DEBUG

这会将所有 SQL 语句输出到控制台。但没有注入变量。这应该可以帮助您进行故障排除。

于 2018-09-27T10:28:24.950 回答
3

H2 引导脚本由ScriptUtils处理

因此,在 application.properties 中增加它的日志级别:

logging.level.org.springframework.jdbc.datasource.init.ScriptUtils=DEBUG
于 2020-04-12T10:08:03.687 回答