Это лучшее решение, которое я нашел с помощью клиента Python
# Initialize the scroll
page = es.search(
index = 'yourIndex',
doc_type = 'yourType',
scroll = '2m',
search_type = 'scan',
size = 1000,
body = {
# Your query's body
})
sid = page['_scroll_id']
scroll_size = page['hits']['total']
# Start scrolling
while (scroll_size > 0):
print "Scrolling..."
page = es.scroll(scroll_id = sid, scroll = '2m')
# Update the scroll ID
sid = page['_scroll_id']
# Get the number of results that we returned in the last scroll
scroll_size = len(page['hits']['hits'])
print "scroll size: " + str(scroll_size)
# Do something with the obtained page
https://gist.github.com/drorata/146ce50807d16fd4a6aa
Использование Java-клиента
import static org.elasticsearch.index.query.QueryBuilders.*;
QueryBuilder qb = termQuery("multi", "test");
SearchResponse scrollResp = client.prepareSearch(test)
.addSort(FieldSortBuilder.DOC_FIELD_NAME, SortOrder.ASC)
.setScroll(new TimeValue(60000))
.setQuery(qb)
.setSize(100).execute().actionGet(); //100 hits per shard will be returned for each scroll
//Scroll until no hits are returned
do {
for (SearchHit hit : scrollResp.getHits().getHits()) {
//Handle the hit...
}
scrollResp = client.prepareSearchScroll(scrollResp.getScrollId()).setScroll(new TimeValue(60000)).execute().actionGet();
} while(scrollResp.getHits().getHits().length != 0); // Zero hits mark the end of the scroll and the while loop.
https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-search-scrolling.html
Изменить: установить пакет NuGet System.IO.Abstractions
.
Этот пакет не существовал, когда этот ответ был первоначально принят. Исходный ответ представлен ниже для исторического контекста:
Вы можете сделать это, создав интерфейс:
interface IFileSystem { bool FileExists (строка имя_файла); DateTime GetCreationDate (строка fileName); }
и создание «реальной» реализации, которая использует System.IO.File.Exists () и т.д. Затем вы можете смоделировать этот интерфейс, используя макет фреймворка; Я рекомендую Moq .
Изменить: кто-то сделал это и любезно разместил в Интернете здесь .
Я использовал этот подход для имитации DateTime.UtcNow в IClock интерфейс (действительно полезен для нашего тестирования, чтобы иметь возможность контролировать поток времени!), и более традиционно, ISqlDataAccess интерфейс.
Другой подход может заключаться в использовании TypeMock , это позволяет вам перехватывать вызовы классов и заглушать их. Однако это стоит деньги, и их нужно будет установить на ПК всей вашей команды и ваш сервер сборки для запуска, также, по-видимому, он не будет работать для файл System.IO.File, так как он не может заглушить mscorlib .
Вы также можете просто согласиться с тем, что некоторые методы нельзя тестировать и протестируйте их в отдельных медленных интеграционных / системных тестах suite.
Я не уверен, как бы вы смоделировали файловую систему. Что вы могли бы сделать, так это написать настройку тестового устройства, которая создает папку и т.д. с необходимой структурой для тестов. Метод teardown очистит его после запуска тестов.
Отредактировано для добавления: Поразмыслив немного над этим, я не думаю, что вы хотите имитировать файловую систему, чтобы протестировать этот тип методов. Если вы имитируете файловую систему, чтобы вернуть истину, если определенный файл существует, и использовать это в своем тесте метода, который проверяет, существует ли этот файл, то вы почти ничего не тестируете. Имитация файловой системы была бы полезна, если вы хотите протестировать метод, который зависел от файловой системы, но активность файловой системы не была неотъемлемой частью тестируемого метода.
Было бы сложно имитировать файловую систему в тесте, поскольку файловые API .NET на самом деле не основаны на интерфейсах или расширяемых классах, которые можно было бы имитировать.
Однако,
Чтобы ответить на ваш конкретный вопрос: Нет, нет библиотек, которые позволили бы вам имитировать вызовы файлового ввода-вывода (о которых я знаю). Это означает, что «правильное» модульное тестирование ваших типов потребует, чтобы вы приняли это ограничение во внимание при определении ваших типов.
Краткое примечание о том, как я определяю «правильный» модульный тест. Я считаю, что модульные тесты должны подтвердить, что вы получаете ожидаемый результат (будь то исключение, вызов метода и т. Д.) При условии известных входных данных. Это позволяет вам настроить условия модульного тестирования как набор входов и / или входных состояний. Наилучший способ, который я нашел для этого, - использование сервисов на основе интерфейса и внедрения зависимостей, так что каждая ответственность, внешняя по отношению к типу, предоставляется через интерфейс, передаваемый через конструктор или свойство.
Итак, имея это в виду, вернемся к вашему вопросу. Я имитировал вызовы файловой системы, создав интерфейс IFileSystemService
вместе с реализацией FileSystemService
, которая является просто фасадом над методами файловой системы mscorlib. Затем в моем коде используется IFileSystemService
, а не типы mscorlib. Это позволяет мне подключать стандартную FileSystemService
, когда приложение работает, или имитировать IFileSystemService
в моих модульных тестах. Код приложения один и тот же независимо от того, как оно выполняется, но базовая инфраструктура позволяет легко протестировать этот код.
Я признаю, что использовать оболочку вокруг объектов файловой системы mscorlib сложно, но в этих конкретных сценариях , это стоит дополнительных усилий, поскольку тестирование становится намного проще и надежнее.
Вам, вероятно, придется создать контракт, чтобы определить, что вам нужно от файловой системы, а затем написать оболочку для этих функций. В этот момент вы сможете имитировать или исключить реализацию.
Пример:
interface IFileWrapper { bool Exists(String filePath); }
class FileWrapper: IFileWrapper
{
bool Exists(String filePath) { return File.Exists(filePath); }
}
class FileWrapperStub: IFileWrapper
{
bool Exists(String filePath)
{ return (filePath == @"C:\myfilerocks.txt"); }
}
Я бы согласился с ответом Джейми Айдэ. Не пытайтесь высмеивать то, чего не писали. Появятся всевозможные зависимости, о которых вы не знали - запечатанные классы, невиртуальные методы и т. Д.
Другой подход состоял бы в том, чтобы обернуть соответствующие методы чем-то, что можно подделывать. например, создайте класс под названием FileWrapper, который разрешает доступ к методам File, но это то, что вы можете имитировать.
В настоящее время мы используем проприетарный механизм обработки данных, и его API не представлен в виде интерфейсов, поэтому мы вряд ли сможем провести модульное тестирование нашего кода доступа к данным. Тогда я тоже согласился с подходом Мэтта и Джозефа.
Создание интерфейса и имитация его для тестирования - самый чистый путь. Однако в качестве альтернативы вы можете взглянуть на фреймворк Microsoft Moles .
Я нашел следующие решения этой проблемы:
В конечном итоге я использую все вышеперечисленные методы, в зависимости от того, что я пишу. Но большую часть времени я прихожу к выводу, что абстракция неправильна, когда я пишу модульные тесты, которые влияют на ввод-вывод.