手动触发SpeechRecognizedEvent

时间:2019-03-20 14:04:17

标签: c# speech

我需要手动触发SpeechRecognizedEvent进行单元测试,所以我不能使用SpeechRecognitionEngine中的EmulateSpeech方法

编辑:

我已经将SpeechRecognition封装到一个单独的Class中,该类具有自己的接口来模拟它。

我需要调用该事件,因为我有一个AutoResetEvent,在事件期间我会对其进行Set()设置。单元测试需要进行此操作。

2 个答案:

答案 0 :(得分:0)

单元测试的一般想法是不要使用真实的东西:

  1. 速度慢(例如数据库)
  2. 经常被戳的危险(例如Google Search API)
  3. 不可用(例如网络服务或硬件)

对于这种情况,您假设使用模拟/存根。换句话说,事物的行为相同,但实际上在您的完全控制之下。

在您的情况下,SpeechRecognitionEngine即使可用,对于单元测试来说也太麻烦了。谁/会说些什么?即使触发事件,为什么还要实例化真实SpeechRecognitionEngine的实例?

查看MSDN中的SpeechRecognitionEngine定义表明它没有实现接口,这意味着很难进行模拟/存根。

在这种情况下,您需要将SpeechRecognitionEngine包装到实现您的接口的自己的类中。然后,您所需要做的就是拥有两种接口实现,一种实现带有真实的SpeechRecognitionEngine来实现真正的语音识别,另一种实现用于单元测试的类,这只会模仿您自己的回调,而不是使用{{ 1}}事件。

您只需将一个实例交换为另一个实例,您的代码就不会有所不同,因为它们正在实现单个接口。

如果您只想模拟事件,则只需调用事件处理程序即可,因为这是一种方法。或者,如果您无法创建某些SpeechRecognized,则使用另一种方法。但是问题在于,您必须从类的外部公开内部方法(例如,将其标记为EventArgspublic),这确实令人讨厌。

internal

然后在测试中,您只需调用类似于以下内容的内容:

private void recognizer_SpeechRecognized(object sender, SpeechRecognizedEventArgs e)
{
    this.ProcessSpeechRecognition(e.Result);
}

public void ProcessSpeechRecognition(RecognitionResult result)
{
    // your logic here
}

答案 1 :(得分:0)

尽管在此之前发布了一个答案,该答案描述了TDD的最佳做法;这是特定于SpeechRecognitionEngine的答案。

Microsoft已经考虑过模拟语音识别。这是SpeechRecognitionEngine.EmulateRecognize Method的MSDN文章:

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