0

我已经使用测试容器为 spring boot 项目设置了集成测试(使用 postgresql 设置了一个 docker 实例)。如果我正在测试的存储库不使用本机查询,则测试效果很好。但是,每当存储库包含本机查询时,我都会收到以下错误:ERROR: relation "my_table_here" does not exist. 如何让我的测试配置工作以允许本机查询?

下面是我的测试设置:

@RunWith(SpringRunner.class)
public class TestPostgresql {

    @ClassRule
    public static PostgreSQLContainer postgreSQLContainer = PostgresDbContainer.getInstance();

    /**
     * ************ REPOSITORIES ************
     */
    @Autowired
    NativeQueryRepository nativeQueryRepository;

    @TestConfiguration
    @EnableJpaAuditing
    @EnableJpaRepositories(
            basePackageClasses = {
                    NativeQueryRepository.class
            })
    @ComponentScan(
            basePackages = {
                    "com.company.project.package.repository"
            }
    )
    static class PostgresConfiguration {

        /**
         * ************ DATABASE SETUP ************
         */
        @Bean
        public DataSource dataSource() {
            DriverManagerDataSource dataSource = new DriverManagerDataSource();
            dataSource.setUrl(postgreSQLContainer.getJdbcUrl());
            dataSource.setUsername(postgreSQLContainer.getUsername());
            dataSource.setPassword(postgreSQLContainer.getPassword());
            return dataSource;
        }

        @Bean
        public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
            HibernateJpaVendorAdapter vendorAdapter = new JpaVendorAdapter();
            vendorAdapter.setDatabase(Database.POSTGRESQL);
            vendorAdapter.setGenerateDdl(true);

            LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
            factory.setJpaVendorAdapter(vendorAdapter);
            factory.setPackagesToScan("com.company.project");
            factory.setDataSource(dataSource());
            return factory;
        }

        @Bean
        public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
            JpaTransactionManager txManager = new JpaTransactionManager();
            txManager.setEntityManagerFactory(entityManagerFactory);
            return txManager;
        }
    }
}

编辑:我相信这与命名策略有关?

有关更多上下文,这里是如何在存储库中使用 nativeQuery 的示例

@Repository
public interface NativeQueryRepository extends JpaRepository<NativeEvent, Long> {

    @Modifying
    @Transactional
    @Query(value = "UPDATE native_event SET state = :state " +
                    "WHERE secondary_id = :secondaryId", nativeQuery = true)
    void updateState(
            @Param("state") String state,
            @Param("secondaryId") String secondaryId);

}

TestPostgresql我还尝试通过添加注释来更新内部静态类的 testProperties :

@TestPropertySource(properties = {
            "spring.jpa.hibernate.naming-strategy=org.springframework.boot.orm.jpa.SpringNamingStrategy"
    })

但是,收到的错误没有改变。

编辑:添加NativeEvent

@Entity
@Table(
        name = "NativeEvent",
        indexes = {
                @Index(name = "idx_native_event_secondary_id", columnList = "secondaryId")
        }
)
@EntityListeners(AuditingEntityListener.class)
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class NativeEvent implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name="secondaryId", nullable=false)
    private String secondaryId;

    @Column(name="state")
    private String state;
}
4

2 回答 2

0

您可以像这样显式分配表名:

@Table(name = "NativeEvent")

但是在您的本机查询中,您对该表有不同的名称:

 @Query(value = "UPDATE native_event ...)

从注释中删除name属性@Table(假设您的命名策略将产生类似native_event的名称)或将本机查询中的表名更改为nativeeventnativeEvent因此在这种情况下只需删除下划线。

有点相关的帖子

于 2019-06-18T06:59:52.803 回答
0

您正在执行手动配置,而不是使用运行时配置。因此,对命名策略的不同处理。相反,您应该重用相同的配置,而不是编写自己的配置。

要么使用@SpringBootTestor@DataJpaTest并且只重新配置DataSource.

使用ApplicationContextInitializer将 JDBC 属性放入ApplicationContext.

@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(initializers = {TestPostgresql.JdbcInitializer.class})
public class TestPostgresql {

    @ClassRule
    public static PostgreSQLContainer postgreSQLContainer = PostgresDbContainer.getInstance();

    /**
     * ************ REPOSITORIES ************
     */
    @Autowired
    NativeQueryRepository nativeQueryRepository;

    static class JdbcInitializer
      implements ApplicationContextInitializer<ConfigurableApplicationContext> {
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
            TestPropertyValues.of(
              "spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
              "spring.datasource.username=" + postgreSQLContainer.getUsername(),
              "spring.datasource.password=" + postgreSQLContainer.getPassword()
            ).applyTo(configurableApplicationContext.getEnvironment());
        }
    }    
}

这将在您的测试中重用运行时的配置。而不是@SpringBootTest您应该能够使用@DataJpaTest(NativeQueryRepository.class)仅对 JPA 进行切片测试。

于 2019-06-19T06:34:40.430 回答