Java Spring启动测试抛出JdbcException“;“未找到表格”;

Java Spring启动测试抛出JdbcException“;“未找到表格”;,java,spring-boot,spring-boot-test,Java,Spring Boot,Spring Boot Test,我在application-test.properties中定义了两个数据源 app.datasource.server.url=jdbc:h2:mem:fooserver app.datasource.server.username=sa app.datasource.server.password= app.datasource.server.driverClassName=org.h2.Driver app.datasource.server.hik

我在application-test.properties中定义了两个数据源

    app.datasource.server.url=jdbc:h2:mem:fooserver
    app.datasource.server.username=sa
    app.datasource.server.password=
    app.datasource.server.driverClassName=org.h2.Driver
    app.datasource.server.hikari.minimumIdle=5
    app.datasource.server.hikari.maximumPoolSize=50
    app.datasource.server.hikari.idleTimeout=50000
    app.datasource.server.hikari.maxLifetime=55000


    app.datasource.manager.url=jdbc:h2:mem:barmanager
    app.datasource.manager.username=sa
    app.datasource.manager.password=
    app.datasource.manager.driverClassName=org.h2.Driver
    app.datasource.manager.hikari.minimumIdle=5
    app.datasource.manager.hikari.maximumPoolSize=50
    app.datasource.manager.hikari.idleTimeout=50000
    app.datasource.manager.hikari.maxLifetime=55000


    # Hibernate ddl auto (create, create-drop, validate, update)
    spring.jpa.hibernate.ddl-auto=create-drop


    #logging
    logging.level.root=info
    logging.file=foobar-rest-test.log

    #required for SpringBootTest does not know why
    spring.main.allow-bean-definition-overriding=true
    spring.h2.console.enabled=true
    spring.h2.console.path=/h2-console
每个数据源都要求名为“foo”的架构可用。这将由schema-fooserver.sql和schema-barmanager.sql创建。在这些sql脚本中,将创建foo架构。因此,我定义了一个DataSourceInitializerbean,在这里我可以定义将加载哪个模式sql文件

@Bean(name = "managerDataSourceInitializer")
public DataSourceInitializer dataSourceInitializer1(@Qualifier("managerDataSource") DataSource datasource) {
    ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
    resourceDatabasePopulator.addScript(new ClassPathResource("schema-barmanager.sql"));        

    DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
    dataSourceInitializer.setDataSource(datasource);
    dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
    return dataSourceInitializer;
}



@Bean(name = "serverDataSourceInitializer")
public DataSourceInitializer dataSourceInitializer1(@Qualifier("serverDataSource") DataSource datasource) {
    ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
    resourceDatabasePopulator.addScript(new ClassPathResource("schema-fooserver.sql"));

    DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
    dataSourceInitializer.setDataSource(datasource);
    dataSourceInitializer.setDatabasePopulator(resourceDatabasePopulator);
    return dataSourceInitializer;
}
在测试开始期间,日志显示这些模式文件已被调用和执行

    2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [schema-fooserver.sql]
    2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils     : 0 returned as update count for SQL: CREATE SCHEMA IF NOT EXISTS FOO
    2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [schema-fooserver.sql] in 0 ms.


    2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils     : Executing SQL script from class path resource [schema-barserver.sql]
    2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils     : 0 returned as update count for SQL: CREATE SCHEMA IF NOT EXISTS FOO
    2019-03-28 15:04:34.252 DEBUG 3124 --- [main] o.s.jdbc.datasource.init.ScriptUtils     : Executed SQL script from class path resource [schema-barserver.sql] in 0 ms.
现在,当我尝试执行测试用例时,由于以下错误而失败:

    28 15:04:36.035 DEBUG 3124 --- [           main] org.hibernate.SQL                        : insert into foo.Account (uid, password_hash, login) values (null, ?, ?)
    Hibernate: insert into foo.Account (uid, password_hash, login) values (null, ?, ?)
    2019-03-28 15:04:36.036 DEBUG 3124 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : could not prepare statement [insert into foo.Account (uid, password_hash, login) values (null, ?, ?)]

    org.h2.jdbc.JdbcSQLException: Tabelle "ACCOUNT" nicht gefunden
    Table "ACCOUNT" not found; SQL statement:
    insert into foo.Account (uid, password_hash, login) values (null, ?, ?) [42102-197]
        at org.h2.message.DbException.getJdbcSQLException(DbException.java:357)
此时,我正试图在我的测试用例中创建一个UserAccount

这是已定义的实体

    @AllArgsConstructor
    @NoArgsConstructor
    @Data
    @Entity
    @Table(name = "foo.Account")
    public class UserEntity {

        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "uid")
        private Long id;
        @Column(name = "login")
        private String username;
        @Column(name = "password_hash")
        private String password;
 ....
下面是测试用例。在createUser方法期间调用before方法时会发生错误

    @RunWith(SpringRunner.class)
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @ActiveProfiles("test")
    @AutoConfigureMockMvc
    public class UserControllerTest {
        private static final Logger LOG = LoggerFactory.getLogger(UserControllerTest.class);

        @LocalServerPort
        private int port;
        TestRestTemplate restTemplate = new TestRestTemplate();
        HttpHeaders headers = new HttpHeaders();
        @Autowired
        private WfcSpringRestApplication controller;

        @Autowired
        private UserRepository repository;

        @Autowired
        private MockMvc mvc;

        private AuthenticationToken authToken;

        @Before
        public void before() throws Exception {
            headers = new HttpHeaders();
            UserEntity user = createTestUser(TEST_ADMIN_USER, TEST_ADMIN_MD5_PW, UserRight.ADMIN);
            UserEntity userService = createTestUser(TEST_SERVICE_USER, TEST_ADMIN_MD5_PW, UserRight.SERVICE);
            getAuthenticationTokenForTestUser(user);

        }


        private UserEntity createTestUser(String username, String md5_password, UserRight right) {

            UserEntity ue = new UserEntity();
            ue.setUsername(username);
            ue.setPassword(md5_password);

            UserRole roleAdmin = new UserRole();
            roleAdmin.setRight(right);

            ue.getRoles().put(roleAdmin.getRight(), roleAdmin);

            repository.save(ue);

            return ue;
        }


        @Test
        public void contextLoads() {
            assertThat(controller).isNotNull();
        }

错误消息中有正确的表名“无法准备语句[插入foo.Account”为什么它会抛出找不到表帐户的异常?

在运行测试之前,您是否检查了表是否已创建?我建议您使用
@primary
注释将数据源bean中的任何一个标记为primary,然后重试。内存中的数据源,我无法对此进行检查。我在异常之前对其进行了调试,然后继续已连接到数据源,但找不到架构或表在我的数据源配置类中将第一个标记为主数据库即使它是内存中的数据库,您也可以通过/h2控制台访问它运行测试之前是否检查了表是否已创建?我建议您将数据源bean中的任何一个标记为primary使用
@Primary
注释并重试。其内存中的数据源,我无法对此进行检查。我在异常之前对其进行了调试并连接到数据源,但找不到架构或表。在我的数据源配置类中,第一个标记为Primary即使它是内存中的数据库,您也可以访问它通过/h2控制台