【问题标题】:Micronaut unit test - how to set default schemaMicronaut 单元测试 - 如何设置默认模式
【发布时间】:2020-05-21 11:01:45
【问题描述】:

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

型号Student.java

@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

@Repository()
public interface StudentRepository extends JpaRepository<Student, Long> {

}

服务StudentService.java

@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

@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")

3.使用application-test.yml文件:[没有效果,查询不选择模式名称]。

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文件指定模式: 但它不起作用,因为模式尚未创建,它将在测试类中创建。所以应用程序不会加载。

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 的同义词 因此,当创建没有模式的查询时,同义词将被替换。为test_schema.student 生成同义词为student
这样查询将被正确翻译:

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

单元测试StudentServiceTest.java

@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");
    }

【问题讨论】:

  • 你试过schema="#{property.file.schema_name}"而不是schema="${property.file.schema_name}"吗?
  • @JeffScottBrown 是的,我也试过了。但它也不起作用。模式需要完整的单词。

标签: java junit5 hikaricp micronaut micronaut-data


【解决方案1】:

在官方文档中有关于GORM 的内容。这可以帮助您解决问题吗?

【讨论】:

    【解决方案2】:

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

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

    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
    

    线

    url: "jdbc:hsqldb:mem:testdb;sql.syntax_ora=true;INIT=runscript from 'classpath:/init_db.sql'"
    

    将使用 init sql 脚本启动数据源,该脚本可以包含默认模式和一些数据(如果需要)。这种方法的缺点是在单元测试开始之前数据库只初始化一次,所以你必须牢记这一点。

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

    那么单元测试就变成了

    @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 (?,?)
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-12-15
      • 1970-01-01
      • 1970-01-01
      • 2021-10-28
      • 1970-01-01
      • 1970-01-01
      • 2014-12-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多