Мне нужно запустить SpeechRecognizedEvent вручную для модульного тестирования, поэтому я не могу использовать метод EmulateSpeech из SpeechRecognitionEngine.
Редактировать:
Я уже инкапсулировал SpeechRecognition в отдельный класс с собственным интерфейсом, чтобы издеваться над ним.
Мне нужно вызвать событие, потому что у меня есть AutoResetEvent, который я установил() во время события. Это необходимо для продолжения модульного теста.
@Frenchy да, я хочу использовать SpeechRecognizedEvent





Общая идея с модульными тестами заключается в том, чтобы не использовать реальные вещи, поскольку они также:
Для таких сценариев вы предполагаете использовать mocks/stubs. Другими словами, вещи, которые ведут себя одинаково, но на самом деле находятся под вашим полным контролем.
В вашем случае SpeechRecognitionEngine, даже если бы он был доступен, был бы слишком громоздким для модульных тестов. Кто/что будет говорить с ним? И даже если вы инициируете событие, зачем создавать экземпляр реального SpeechRecognitionEngine?
Глядя на MSDN для определения SpeechRecognitionEngine, вы видите, что он не реализует интерфейс, а это означает, что его будет сложно имитировать/заглушить.
В этом случае вам нужно обернуть, другими словами, инкапсулировать SpeechRecognitionEngine в свой собственный класс, который реализует ваш интерфейс. Затем все, что вам нужно сделать, это иметь две реализации вашего интерфейса, одну с реальным SpeechRecognitionEngine для реального распознавания речи, а другой класс для модульных тестов, который просто имитирует ваш собственный обратный вызов вместо использования события SpeechRecognized.
Вы просто меняете один экземпляр на другой, и ваш код не увидит разницы, так как они реализуют единый интерфейс.
Если вы просто хотите смоделировать событие, вы просто вызываете обработчик события, так как это метод. Или другой способ, если не получается создать какой-то EventArgs. Но проблема в том, что вам придется выставлять внутренние методы извне вашего класса (например, помечать их public или internal), и это выглядит неприятно.
private void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
this.ProcessSpeechRecognition(e.Result);
}
public void ProcessSpeechRecognition(RecognitionResult result)
{
// your logic here
}
Затем в тесте вы просто вызываете что-то похожее на приведенное ниже:
ProcessSpeechRecognition(new RecognitionResult { Text = "test" });
Я отредактировал свой пост с дополнительной информацией. К сожалению, метод, который вы упомянули внизу своего поста, не работает, потому что у SpeechRecognizedEventArgs нет конструктора, поэтому вы не можете создать его новый экземпляр.
@Dardguy, как вы уже поняли, некоторые API не подходят для тестирования. Это более веская причина для создания удобных для тестирования оболочек вокруг неудобных для тестирования сторонних классов. Если вы хотите сократить усилия и просто нуждаетесь в быстром и грязном способе протестировать свой код после события, просто вызовите свой собственный метод из обработчика события и надейтесь, что у вас нет ошибки в середине. Затем вызовите свой собственный метод из теста, как это сделал бы обработчик событий в реальном сценарии.
Другая проблема заключается в том, что класс RecognitionResult запечатан, поэтому я не могу его заменить. У вас есть идея, как сделать это чистым способом?
@Dardguy Похоже, Microsoft уже подумала об этом сценарии. Есть простой способ эмулировать событие распознавания. Проверьте SpeechRecognitionEngine.EmulateRecognize Method это на MSDN: docs.microsoft.com/en-us/dotnet/api/…
Несмотря на то, что ранее был опубликован ответ, в котором описываются лучшие практики для TDD; вот ответ, специфичный для SpeechRecognitionEngine.
Microsoft уже подумала об эмуляции распознавания речи. Вот статья MSDN для SpeechRecognitionEngine.EmulateRecognize Method:
вы просто хотите использовать SpeechRecoginzedEvent?