Вручную запустить SpeechRecognizedEvent

#c# #speech

#c# #речь

Вопрос:

Мне нужно запустить SpeechRecognizedEvent вручную для модульного тестирования, поэтому я не могу использовать метод EmulateSpeech из SpeechRecognitionEngine

Редактировать:

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

Мне нужно вызвать событие, потому что у меня есть AutoResetEvent, который я установил () во время события. Это необходимо для продолжения модульного теста.

Комментарии:

1. вы просто хотите использовать SpeechRecoginzedEvent?

2. @Frenchy да, я хочу использовать SpeechRecognizedEvent

Ответ №1:

Общая идея модульных тестов заключается в том, чтобы не использовать реальные вещи, поскольку они либо:

  1. Медленно (например, база данных)
  2. Опасно часто использовать (например, Google Search API)
  3. Недоступно (например, веб-сервис или аппаратное обеспечение)

Для таких сценариев предполагается использовать макеты / заглушки. Другими словами, вещи, которые ведут себя идентично, но на самом деле находятся под вашим полным контролем.

В вашем случае SpeechRecognitionEngine , даже если это может быть доступно, было бы слишком громоздко для модульных тестов. Кто / что будет говорить с ним? И даже если вы запускаете событие, зачем создавать экземпляр real SpeechRecognitionEngine ?

Поиск SpeechRecognitionEngine определения в MSDN показывает, что в нем не реализован интерфейс, что означает, что было бы сложно создать макет / заглушку.

В этом случае вам нужно обернуть, другими словами, инкапсулировать SpeechRecognitionEngine в свой собственный класс, который реализует ваш интерфейс. Затем все, что вам нужно сделать, это иметь две реализации вашего интерфейса, одну с real 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" });
  

Комментарии:

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

2. @Dardguy как вы уже поняли, некоторые API не подходят для тестирования. Это более веская причина для создания удобных для тестирования оболочек вокруг сторонних классов, не подходящих для тестирования. Если вы хотите сократить усилия и вам просто нужен быстрый и грязный способ протестировать свой код после события, просто вызовите свой собственный метод из обработчика событий и надейтесь, что у вас нет ошибки в середине. Затем вызовите свой собственный метод из test, как это сделал бы обработчик событий в реальном сценарии.

3. Другая проблема заключается в том, что класс RecognitionResult закрыт, поэтому я не могу его заменить. У вас есть идея, как это сделать чистым способом?

4. @Dardguy Похоже, Microsoft уже продумала этот сценарий. Есть простой способ эмулировать событие распознавания. Проверьте SpeechRecognitionEngine.EmulateRecognize Method это на MSDN: learn.microsoft.com/en-us/dotnet/api /…

Ответ №2:

Несмотря на публикацию ответа ранее, в котором описываются лучшие практики для TDD; вот ответ, специфичный для SpeechRecognitionEngine .

Microsoft уже подумала об эмуляции распознавания речи. Вот статья MSDN для SpeechRecognitionEngine.EmulateRecognize Method :

https://learn.microsoft.com/en-us/dotnet/api/system.speech.recognition.speechrecognitionengine.emulaterecognize