首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Micronaut单元测试-如何设置默认模式

Micronaut单元测试-如何设置默认模式
EN

Stack Overflow用户
提问于 2020-05-21 11:01:45
回答 2查看 930关注 0票数 2

我试图使用单元测试,但是找不到在这个示例应用程序中设置default schema的方法。这是一个简单的micronaut-data 示例,有modelrepositoryservice。应用程序中使用HSQL数据库,并使用Hikari db池micronaut-jdbc-hikari

模型Student.java

代码语言:javascript
复制
@Entity
@Table(name="student") 
class Student{

  @Id
  @Column(name="id")
  private Long id;   

  @Column(name="name")     
  private String name;

  public Long getId(){
    return this.id;
  }
  public String getName(){
    return this.name;
  }
  public void setId(Long id){
    this.id = id;
  }
  public void setName(String name){
    this.name = name;
  }
}

仓库StudentRepository.java

代码语言:javascript
复制
@Repository()
public interface StudentRepository extends JpaRepository<Student, Long> {

}

服务StudentService.java

代码语言:javascript
复制
@Singleton
public class StudentService {

    @Inject
    StudentRepository studentRepository;

    public Student getStudentById(Long id) {
        Optional<Student> optional = StudentRepository.findById(id);
        if (optional.isPresent()) {
            return optional.get();
        }
        throw new ApplicationException("No matching data available");
    }

}

单元测试StudentServiceTest.java

代码语言:javascript
复制
@MicronautTest
public class StudentServiceTest {

    @RegisterExtension
    static InMemoryDbExtension inMemoryDbExtension = new InMemoryDbExtension.InMemoryDbBuilder()
            .withSchemaName("TEST_SCHEMA")
            .withSchemaSqls(new String[]{"src/test/resources/memdb/schema.sql"})
            .withTestDataSqls(new String[]{"src/test/resources/db/test.sql"})
            .build();
    private static InMemoryHsqlDb inMemoryHsqlDb;
    @Inject
    private StudentService studentService;

    @BeforeAll
    public static void runBeforeAll(InMemoryHsqlDb inMemoryHsqlDb) {
        StudentServiceTest.inMemoryHsqlDb = inMemoryHsqlDb;
    }

    @Test
    public void shouldTestGetById() {
        Student s = new Student();
        s.setId(5);
        s.setName("XYZ");
        studentService.save(s); // query generated: insert into student(id, name) values (?,?)
    }
}

问题:--我可以找到一些方法来设置默认模式,但每个方法都有问题。

  1. 使用存储库注释@Table(schema="TEST_SCHEMA", name="student") <=工作。但是不能硬编码模式名
  2. 使用存储库注释@Table(schema="#{property.file.schema_name}", name="student") <= Spring表达式,SpEL无法工作

3.使用application-test.yml文件:不起作用,查询不选择模式名。

代码语言:javascript
复制
jpa:
      default:
        entity-scan:
          packages: 'com.example.model'
          properties:
            hibernate:
              hbm2ddl:
                auto: update
              default-schema: TEST_SCHEMA # <= default schema, also tried default_schema
              show_sql: true

4.在数据源中使用指定模式的application-test.yml文件:但是它不能工作,因为该模式尚未创建,它将在测试类中创建。所以应用程序不会加载。

代码语言:javascript
复制
datasources:
  default:
    driverClass: org.hsqldb.jdbc.JDBCDriver
    url: jdbc:hsqldb:mem:testdb;sql.syntax_ora=true
    username: sa
    autoCommit: false
    maximumPoolSize: 1
    leakDetectionThreshold: 180000
    poolName: hikariConnectionPoolName
    minimumIdle: 5
    schema: TEST_SCHEMA  # <= default schema

=========================================================

目前的解决方案

使用同义词作为table_name来表示schema_name.table_name,因此,在没有模式的情况下创建查询时,将替换同义词。为student生成test_schema.student的同义词

,以便正确翻译查询:

生成的查询=> insert into student(id, name) values (?,?)

翻译查询=> insert into test_schema.student(id, name) values (?,?)

单元测试StudentServiceTest.java

代码语言:javascript
复制
@BeforeAll
    public static void runBeforeAll(InMemoryHsqlDb inMemoryHsqlDb) {
        StudentServiceTest.inMemoryHsqlDb = inMemoryHsqlDb;
        // workaround for not using schema
        inMemoryHsqlDb.getJdbi().open().execute("create synonym STUDENT for TEST_SCHEMA.STUDENT");
    }
EN

回答 2

Stack Overflow用户

发布于 2020-05-24 11:39:25

在官方文档中,有一些关于戈姆的内容。这能帮你解决你的问题吗?

票数 0
EN

Stack Overflow用户

发布于 2020-05-26 10:02:27

您可以尝试在插入数据库时执行脚本,并在加载数据库时加载架构:

在application-test.yml中,可以更改数据源配置:

代码语言:javascript
复制
datasources:
  default:
    driverClass: org.hsqldb.jdbc.JDBCDriver
    url: "jdbc:hsqldb:mem:testdb;sql.syntax_ora=true;INIT=runscript from 'classpath:/init_db.sql'"
    username: sa
    autoCommit: false
    maximumPoolSize: 1
    leakDetectionThreshold: 180000
    poolName: hikariConnectionPoolName
    minimumIdle: 5

线

代码语言:javascript
复制
url: "jdbc:hsqldb:mem:testdb;sql.syntax_ora=true;INIT=runscript from 'classpath:/init_db.sql'"

将使用可以包含默认架构的init sql脚本启动数据源,并在需要时提供一些数据。这种方法的缺点是数据库在单元测试开始之前只初始化一次,所以您必须记住这一点。

init_db.sql scprit必须位于测试资源文件夹中,并且应该包含脚本"src/ test /resources/memdb/schema.sql“和"src/test/resources/db/test.sql”的内容。

然后单元测试变成

代码语言:javascript
复制
@MicronautTest
public class StudentServiceTest {

    @Inject
    private StudentService studentService;

    @Test
    public void shouldTestGetById() {
        Student s = new Student();
        s.setId(5);
        s.setName("XYZ");
        studentService.save(s); // query generated: insert into student(id, name) values (?,?)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61932999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档