Spring引导集成测试中的Hibernate搜索问题

Spring引导集成测试中的Hibernate搜索问题,spring,spring-boot,integration-testing,hibernate-search,Spring,Spring Boot,Integration Testing,Hibernate Search,我正在使用Spring Boot 2.1.0。发布和Hibernate Search 5.10.8。最终版 我在Spring Boot的集成测试中遇到了Hibernate搜索问题 集成测试 @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @DirtiesContext(classMode = DirtiesContext.ClassMo

我正在使用Spring Boot 2.1.0。发布Hibernate Search 5.10.8。最终版

我在Spring Boot的集成测试中遇到了Hibernate搜索问题

集成测试

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@TestPropertySource(locations = "classpath:application-test.properties")
public class FindBookE2ETest {

    private String HTTP_LOCALHOST = "http://localhost:";

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Test
    @Sql({"/book/book.sql"})
    public void findBookByLanguageTest() {
        ResponseEntity<List<BookDTO>> exchange = restTemplate.exchange(HTTP_LOCALHOST + port + "/findBooks/ENG/language", HttpMethod.GET, null, new ParameterizedTypeReference<List<BookDTO>>() {});
        assertThat(exchange.getStatusCode().value()).isEqualTo(HttpStatus.OK.value());
        assertThat(exchange.getBody()).isNotNull();
        assertThat(exchange.getBody().get(0).getLanguage()).isEqualTo("ENG");
    }
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口)
@DirtiesContext(classMode=DirtiesContext.classMode.BEFORE\u每个\u测试\u方法)
@TestPropertySource(locations=“classpath:application test.properties”)
公共类FindBookeTest{
专用字符串HTTP_LOCALHOST=”http://localhost:";
@本地服务器端口
专用int端口;
@自动连线
私有TestRestTemplate;
@试验
@Sql({“/book/book.Sql”})
public void findBookByLanguageTest(){
ResponseEntity exchange=restemplate.exchange(HTTP_LOCALHOST+port+“/findBooks/ENG/language”,HttpMethod.GET,null,新参数化类型引用(){});
assertThat(exchange.getStatusCode().value()).isEqualTo(HttpStatus.OK.value());
assertThat(exchange.getBody()).isNotNull();
断言(exchange.getBody().get(0.getLanguage()).isEqualTo(“ENG”);
}
}
classpath:application test.properties中,我只有spring.datasource.initialization mode=never

Hibernate搜索的实现

@Transactional
@Service("bookService")
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    @PersistenceContext
    private EntityManager entityManager;

     private List<Book> searchBookByLanguage(String value) {
        List<Book> booksByLanguages = bookRepository.findBooksByLanguages(value); //for debug test purpose
        System.out.println("book from repo: " + booksByLanguages.size()); //for debug test purpose

        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
        QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory()
                .buildQueryBuilder()
                .forEntity(Book.class)
                .get();

        Query luceneQuery = queryBuilder
                .keyword()
                .onFields("language")
                .matching(value)
                .createQuery();
        FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(luceneQuery, Book.class);
        List<Book>  resultList = jpaQuery.getResultList();
        return resultList;
    }

    ///rest of the code
}
@Transactional
@服务(“图书服务”)
公共类BookServiceImpl实现BookService{
@自动连线
私人书库;
@持久上下文
私人实体管理者实体管理者;
私有列表searchBookByLanguage(字符串值){
List booksByLanguages=bookRepository.findBooksByLanguages(value);//用于调试测试
System.out.println(“来自repo的书籍:+booksByLanguages.size());//用于调试测试
FullTextEntityManager FullTextEntityManager=Search.getFullTextEntityManager(entityManager);
QueryBuilder QueryBuilder=fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(书本类)
.get();
Query luceneQuery=queryBuilder
.keyword()
.onFields(“语言”)
.匹配(值)
.createQuery();
FullTextQuery jpaQuery=fullTextEntityManager.createFullTextQuery(luceneQuery,Book.class);
List resultList=jpaQuery.getResultList();
返回结果列表;
}
///代码的其余部分
}
src/main/resource下,我有data.sql文件。在test/resource下,我有每个测试的sql文件

我的问题是。
当我运行整个应用程序时,一切正常,但在集成测试no.in findbookbylangagetest()中,hibernate搜索不返回任何值(bookRepository.findBooksByLanguages()返回),我不知道为什么。可能是配置问题

我在测试属性中注释了spring.datasource.initialization mode=never,我得到一个错误,测试中的sql脚本无法插入数据,因为(我不知道为什么)spring从src/main/reource/data.sql下的data.sql获取数据,但该文件不在“test”部分。因此,我在我的测试上面也对sql注释进行了注释,因此使用此配置:

#spring.datasource.initialization mode=never类路径:应用程序测试.properties中

@测试
//@Sql({“/book/book.Sql”})
public void findBookByLanguageTest(){
ResponseEntity exchange=restemplate.exchange(HTTP_LOCALHOST+port+“/findBooks/ENG/language”,HttpMethod.GET,null,新参数化类型引用(){});
assertThat(exchange.getStatusCode().value()).isEqualTo(HttpStatus.OK.value());
assertThat(exchange.getBody()).isNotNull();
断言(exchange.getBody().get(0.getLanguage()).isEqualTo(“ENG”);
}
我的测试成功了

有人知道我的配置有什么问题吗?我希望将我的测试与data.sql分开,并为每个测试使用sql脚本。 也许EntityManager有问题

****在@yrodiere响应后编辑****

我修改了我的FindBooke2Test,现在看起来是这样的

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@TestPropertySource(locations = "classpath:application-test.properties")
public class FindBookE2ETest {

    private String HTTP_LOCALHOST = "http://localhost:";

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private EntityManager entityManager;

    @Before
    public void setUp(){
        entityManager = entityManager.getEntityManagerFactory().createEntityManager();
    }

    @Test
    @Sql({"/book/book.sql"})
    public void findBookByLanguageTest() {
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
        fullTextEntityManager.createIndexer().startAndWait();

        ResponseEntity<List<BookDTO>> exchange = restTemplate.exchange(HTTP_LOCALHOST + port + "/findBooks/ENG/language", HttpMethod.GET, null, new ParameterizedTypeReference<List<BookDTO>>() {});
        assertThat(exchange.getStatusCode().value()).isEqualTo(HttpStatus.OK.value());
        assertThat(exchange.getBody()).isNotNull();
        assertThat(exchange.getBody().get(0).getLanguage()).isEqualTo("ENG");
    }
}
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=SpringBootTest.webEnvironment.RANDOM\u端口)
@DirtiesContext(classMode=DirtiesContext.classMode.BEFORE\u每个\u测试\u方法)
@TestPropertySource(locations=“classpath:application test.properties”)
公共类FindBookeTest{
专用字符串HTTP_LOCALHOST=”http://localhost:";
@本地服务器端口
专用int端口;
@自动连线
私有TestRestTemplate;
@自动连线
私人实体管理者实体管理者;
@以前
公共作废设置(){
entityManager=entityManager.GetEntityManager工厂().createEntityManager();
}
@试验
@Sql({“/book/book.Sql”})
public void findBookByLanguageTest(){
FullTextEntityManager FullTextEntityManager=Search.getFullTextEntityManager(entityManager);
fullTextEntityManager.createIndexer().startAndWait();
ResponseEntity exchange=restemplate.exchange(HTTP_LOCALHOST+port+“/findBooks/ENG/language”,HttpMethod.GET,null,新参数化类型引用(){});
assertThat(exchange.getStatusCode().value()).isEqualTo(HttpStatus.OK.value());
assertThat(exchange.getBody()).isNotNull();
断言(exchange.getBody().get(0.getLanguage()).isEqualTo(“ENG”);
}
}

现在一切正常。Thx.

我很惊讶你居然能让测试正常运行。你负责在某处执行任务吗?对于初始化,仅通过SQL命令在数据库中插入数据对于Hibernate搜索是不够的,因为您绕过了Hibernate ORM:您还需要从数据库中提取数据并对其进行索引,这就是问题所在
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
@TestPropertySource(locations = "classpath:application-test.properties")
public class FindBookE2ETest {

    private String HTTP_LOCALHOST = "http://localhost:";

    @LocalServerPort
    private int port;

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private EntityManager entityManager;

    @Before
    public void setUp(){
        entityManager = entityManager.getEntityManagerFactory().createEntityManager();
    }

    @Test
    @Sql({"/book/book.sql"})
    public void findBookByLanguageTest() {
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
        fullTextEntityManager.createIndexer().startAndWait();

        ResponseEntity<List<BookDTO>> exchange = restTemplate.exchange(HTTP_LOCALHOST + port + "/findBooks/ENG/language", HttpMethod.GET, null, new ParameterizedTypeReference<List<BookDTO>>() {});
        assertThat(exchange.getStatusCode().value()).isEqualTo(HttpStatus.OK.value());
        assertThat(exchange.getBody()).isNotNull();
        assertThat(exchange.getBody().get(0).getLanguage()).isEqualTo("ENG");
    }
}