Martin Fowler записал превосходная статья об этом предмете. От той статьи:
Meszaros использует термин Тест Дважды, поскольку общее обозначение для любого отчасти симулирует объект, используемый вместо реального объекта для тестирования. Название происходит от понятия Трюка Дважды в фильмах. (Одна из его целей состояла в том, чтобы избегать использования любого имени, которое уже широко использовалось.) Meszaros тогда определил четыре конкретных вида дважды:
- Фиктивные объекты раздаются, но никогда на самом деле используются. Обычно они просто используются для заполнения списков параметров.
- Поддельные объекты на самом деле имеют рабочие реализации, но обычно берут некоторый ярлык, который делает их не подходящими для производства (в базе данных памяти, хороший пример).
- Тупики предоставляют консервированные ответы на вызовы, выполненные во время теста, обычно не отвечающего вообще ни на что снаружи, что программируется в для теста. Тупики могут также записать информацию о вызовах, таких как почтовый тупик шлюза, который помнит сообщения, которые она 'отправила', или возможно только, сколько сообщений она 'отправила'.
- Насмешки - то, о чем мы говорим здесь: объекты, предварительно запрограммированные с ожиданиями, которые формируют спецификацию вызовов, которые они, как ожидают, получат.
Для помещения его в мои собственные слова: фиктивные объекты "ожидают", что определенные методы будут названы на них, и обычно заставят модульный тест перестать работать, если их надежды не будут оправданы. Тупиковые объекты обеспечивают консервированные ответы (и может быть автоматически сгенерирован библиотеками помощника), но обычно делайте не , непосредственно заставляют модульный тест перестать работать. Они обычно просто используются так, чтобы объект, который Вы тестируете, получил данные, это должно сделать свою работу.
Я бы использовал кольцевой буфер временных меток с фиксированным размером M. Каждый раз, когда вызывается метод, вы проверяете самую старую запись, и если она меньше N секунд назад вы выполняете и добавляете еще одну запись, иначе вы спите из-за разницы во времени.
Конкретно, вы должны иметь возможность реализовать это с помощью DelayQueue
. Инициализируйте очередь с помощью экземпляров M
Delayed
с их задержкой, изначально установленной на ноль. При поступлении запросов к методу принимает
маркер, что приводит к блокировке метода до тех пор, пока не будет выполнено требование регулирования. Когда маркер был взят, добавьте
новый маркер в очередь с задержкой N
.
Прочтите об алгоритме Token bucket . По сути, у вас есть ведро с жетонами. Каждый раз, когда вы выполняете метод, вы берете токен. Если жетонов больше нет, вы блокируете их, пока не получите один. Между тем, есть какой-то внешний субъект, который пополняет токены с фиксированным интервалом.
Я не знаю библиотеки для этого (или чего-то подобного).
Хотя это не то, что вы просили, ThreadPoolExecutor
, который предназначен для ограничения до M одновременных запросов вместо M запросов за N секунд, также может быть полезен.