Как проверить, что FileSystemWatcher вызывает правильные события?

Я использую `System.IO.FileSystemWatcher` в одной из
моих служб. Я хочу проверить, что, когда файл, контролируемый,
изменяется, я получаю уведомление.

Я думал о том, что фоновый поток меняет файл. В тесте я бы
присоединился к этой теме. Тогда я могу утверждать, что вызываются
правильные события. Я мог бы подписаться на обратный вызов для
захвата, если событие было вызвано.

Я не проводил никаких испытаний, связанных с потоками, поэтому я
не уверен, что это лучший способ справиться с этим, или если в Moq
или MSpec есть встроенные способы, которые помогут
протестировать.

Moq или MSpec не имеют ничего специально встроенного, что
поможет вам сделать это, за исключением некоторых интересных
синтаксиса или функций, которые помогут вам организовать ваш тест.
Я думаю, ты на правильном пути.

Мне любопытно, как ваш сервис предоставляет файлы с измененными
уведомлениями. Открывает ли он их публично для тестирования? Или
код `FileSystemWatcher` полностью скрыт внутри службы?
Если служба не просто передает уведомление о событиях вверх и вниз,
вы должны извлечь свой мониторинг файлов, чтобы он мог быть легко
протестирован.

Вы можете сделать это с помощью событий .NET или обратных
вызовов или чего-то еще. Независимо от того, как вы это делаете, я
бы написал тест что-то вроде этого ...

```
[Subject("File monitoring")]
public class When_a_monitored_file_is_changed
{
    Establish context =() => 
    {
       //depending on your service file monitor design, you would
       //attach to your notification
        _monitor.FileChanged +=() => _changed.Set();

       //or pass your callback in
        _monitor = new ServiceMonitor(() => _changed.Set());
    }

    Because of =() =>//modify the monitored file;

   //Wait a reasonable amount of time for the notification to fire, but not too long that your test is a burden
    It should_raise_the_file_changed_event =() => _changed.WaitOne(TimeSpan.FromMilliseconds(100)).ShouldBeTrue();

    private static readonly ManualResetEvent _changed = new ManualResetEvent();
}

```