手动触发SpeechRecognizedEvent

问题描述 投票:-1回答:2

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

编辑:

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

我需要调用Event,因为我有一个AutoResetEvent,我在事件期间设置了Set()。单元测试需要这样才能继续。

c# speech
2个回答
0
投票

单元测试的一般想法不是使用真实的东西,因为它们:

  1. 慢(例如数据库)
  2. 经常发飙(例如谷歌搜索API)
  3. 不可用(例如网络服务或硬件)

对于这种情况,您可以使用模拟/存根。换句话说,表现相同的事物,但实际上是在你的完全控制之下。

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

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

对于这种情况,您需要换行,换句话说,将SpeechRecognitionEngine封装到您自己的类中,该类实现您的接口。然后,您需要做的就是有两个接口实现,一个用真正的SpeechRecognitionEngine实现真正的语音识别,另一个用于单元测试,它只是模仿你自己的回调,而不是使用SpeechRecognized事件。

您只需将一个实例交换为另一个实例,并且您的代码将看不到差异,因为它们正在实现单个接口。

如果您只想模拟事件,则只需调用事件处理程序,因为这是一种方法。或者另一种方法,如果你不能创建一些EventArgs。但问题是你必须从你的课外暴露内部方法(例如标记为publicinternal),这看起来很糟糕。

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" });

0
投票

尽管在描述TDD的最佳实践之前发布了答案;这是SpeechRecognitionEngine特有的答案。

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

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

© www.soinside.com 2019 - 2024. All rights reserved.