package com.epam.wilma.message.search.lucene.search; /*========================================================================== Copyright 2013-2017 EPAM Systems This file is part of Wilma. Wilma is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Wilma is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Wilma. If not, see <http://www.gnu.org/licenses/>. ===========================================================================*/ import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import java.io.IOException; import java.util.List; import org.apache.lucene.document.Document; import org.apache.lucene.document.StringField; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; import org.apache.lucene.search.TopDocs; import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.MockitoAnnotations; import org.mockito.internal.util.reflection.Whitebox; import org.slf4j.Logger; import org.testng.Assert; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.epam.wilma.message.search.domain.exception.QueryCannotBeParsedException; import com.epam.wilma.message.search.domain.exception.SystemException; import com.epam.wilma.message.search.lucene.search.helper.CurrentTimeProvider; import com.epam.wilma.message.search.lucene.search.helper.IndexReaderFactory; import com.epam.wilma.message.search.lucene.search.helper.IndexSearcherFactory; /** * Unit tests for the class {@link LuceneSearchEngine}. * @author Tunde_Kovacs * */ public class LuceneSearchEngineTest { private static final String TEXT = "text"; private static final String FIELD_PATH = "path"; private static final int TOP_QUERY_HITS = 10000; private ScoreDoc[] scoreDocs; private TopDocs queryResult; private Document document; @Mock private IndexReader indexReader; @Mock private IndexSearcher indexSearcher; @Mock private IndexReaderFactory readerFactory; @Mock private QueryParser queryParser; @Mock private IndexSearcherFactory searcherFactory; @Mock private CurrentTimeProvider currentTimeProvider; @Mock private Logger logger; @Mock private Query query; @InjectMocks private LuceneSearchEngine underTest; @BeforeMethod public void setUp() { underTest = spy(new LuceneSearchEngine()); MockitoAnnotations.initMocks(this); Whitebox.setInternalState(underTest, "topQueryHits", TOP_QUERY_HITS); scoreDocs = new ScoreDoc[1]; scoreDocs[0] = new ScoreDoc(12, 12); queryResult = new TopDocs(TOP_QUERY_HITS, scoreDocs, 10); document = new Document(); document.add(new StringField(FIELD_PATH, TEXT, null)); } @Test public void testInitQueryParserProperties() { //GIVEN in setUp //WHEN underTest.initQueryParserProperties(); //THEN verify(queryParser).setLowercaseExpandedTerms(true); verify(queryParser).setAllowLeadingWildcard(true); } @Test public void testSearchForTextShouldReturnText() throws IOException, ParseException { //GIVEN given(readerFactory.create(true)).willReturn(indexReader); given(searcherFactory.create(indexReader)).willReturn(indexSearcher); given(queryParser.parse(TEXT)).willReturn(query); given(indexSearcher.search(query, TOP_QUERY_HITS)).willReturn(queryResult); doReturn(document).when(underTest).getDocument(12); doNothing().when(underTest).closeIndexReader(); //WHEN List<String> actual = underTest.searchForText(TEXT); //THEN Assert.assertEquals(actual.get(0), TEXT); } @Test(expectedExceptions = QueryCannotBeParsedException.class) public void testSearchForTextWhenCannotParseQueryShouldThrowError() throws IOException, ParseException { //GIVEN given(readerFactory.create(true)).willReturn(indexReader); given(searcherFactory.create(indexReader)).willReturn(indexSearcher); given(queryParser.parse(TEXT)).willThrow(new ParseException()); //WHEN underTest.searchForText(TEXT); //THEN it should throw exception } @Test(expectedExceptions = SystemException.class) public void testSearchForTextWhenCannotCreateIndexReadertShouldThrowException() throws IOException { //GIVEN given(readerFactory.create(true)).willThrow(new IOException()); //WHEN underTest.searchForText(TEXT); //THEN it should throw exception } @Test public void testSearchForTextWhenCannotCloseIndexReadertShouldLogError() throws IOException, ParseException { //GIVEN Whitebox.setInternalState(underTest, "logger", logger); given(readerFactory.create(true)).willReturn(indexReader); given(searcherFactory.create(indexReader)).willReturn(indexSearcher); given(queryParser.parse(TEXT)).willReturn(query); given(indexSearcher.search(query, TOP_QUERY_HITS)).willReturn(queryResult); doReturn(document).when(underTest).getDocument(12); doThrow(new IOException()).when(underTest).closeIndexReader(); //WHEN underTest.searchForText(TEXT); //THEN verify(logger).error(Mockito.anyString()); } }