我需要手动触发 SpeechRecognizedEvent 进行单元测试,因此我无法使用 SpeechRecognitionEngine 中的 EmulateSpeech 方法
编辑:
我已经将语音识别封装到一个单独的类中,该类具有自己的接口来模拟它。
我需要调用事件,因为我有一个自动重置事件,我在事件期间设置()。单元测试需要这样做才能继续。
单元测试的一般思路是不使用真实的东西,因为它们也:
- 慢(例如数据库)
- 经常戳很危险(例如谷歌搜索API)
- 不可用(例如 Web 服务或硬件)
对于此类场景,您假设使用模拟/存根。换句话说,行为相同,但实际上在您的完全控制之下。
在您的情况下,SpeechRecognitionEngine
即使它可能可用,对于单元测试来说也太麻烦了。谁/什么会对它说话?即使触发了一个事件,为什么要实例化一个真实SpeechRecognitionEngine
的实例?
查看 MSDNSpeechRecognitionEngine
定义表明它没有实现接口,这意味着很难模拟/存根。
对于这种情况,您需要包装,换句话说,将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" });
尽管之前发布了一个答案,描述了TDD的最佳实践;这是一个特定于SpeechRecognitionEngine
的答案。
Microsoft已经考虑过模拟语音识别。以下是 MSDNSpeechRecognitionEngine.EmulateRecognize Method
文章:
https://learn.microsoft.com/en-us/dotnet/api/system.speech.recognition.speechrecognitionengine.emulaterecognize