Вручную запустить SpeechRecognizedEvent - PullRequest
0 голосов
/ 20 марта 2019

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

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

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

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

Ответы [ 2 ]

0 голосов
/ 23 марта 2019

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

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

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

0 голосов
/ 20 марта 2019

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

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

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

В вашем случае 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" });
...