手动触发 SpeechRecognizedEvent
Manually fire SpeechRecognizedEvent
我需要手动触发 SpeechRecognizedEvent 进行单元测试,所以我无法使用 SpeechRecognitionEngine 中的 EmulateSpeech 方法
编辑:
我已经将 SpeechRecognition 封装到一个单独的 Class 中,它有自己的接口来模拟它。
我需要调用该事件,因为我有一个 AutoResetEvent,我在事件期间对其进行了 Set()。单元测试需要这个才能继续。
单元测试的总体思路是不要使用真实的东西,因为它们要么:
- 慢(例如数据库)
- 经常戳很危险(例如Google搜索API)
- 不可用(例如网络服务或硬件)
对于这种情况,您应该使用 mocks/stubs。换句话说,行为相同的事物,但实际上在您的完全控制之下。
在你的情况下 SpeechRecognitionEngine
,即使它可能可用,对于单元测试来说也太麻烦了。 Who/what会说话吗?而且就算触发了事件,为什么要实例化一个真实的实例SpeechRecognitionEngine
?
查看 MSDN 的 SpeechRecognitionEngine
定义表明它没有实现接口,这意味着很难 mock/stub。
对于这种情况,您需要包装,换句话说,将 SpeechRecognitionEngine
封装到您自己的 class 中,它实现了您的接口。然后,您需要做的就是拥有您的接口的两个实现,一个具有真正的 SpeechRecognitionEngine
用于真实的语音识别,另一个具有 class 用于单元测试,它只是模仿您自己的回调,而不是使用 SpeechRecognized
事件。
您只需将一个实例换成另一个实例,您的代码将看不出有什么不同,因为它们实现的是单一接口。
如果你只是想模拟一个事件,你只需要调用一个事件处理器,因为这是一个方法。或者另一种方法,如果你不能创建一些 EventArgs
。但问题是您必须从 class 外部公开内部方法(例如将其标记为 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
.
的答案
微软已经想到了语音识别的仿真。这是 SpeechRecognitionEngine.EmulateRecognize Method
:
的 MSDN 文章
我需要手动触发 SpeechRecognizedEvent 进行单元测试,所以我无法使用 SpeechRecognitionEngine 中的 EmulateSpeech 方法
编辑:
我已经将 SpeechRecognition 封装到一个单独的 Class 中,它有自己的接口来模拟它。
我需要调用该事件,因为我有一个 AutoResetEvent,我在事件期间对其进行了 Set()。单元测试需要这个才能继续。
单元测试的总体思路是不要使用真实的东西,因为它们要么:
- 慢(例如数据库)
- 经常戳很危险(例如Google搜索API)
- 不可用(例如网络服务或硬件)
对于这种情况,您应该使用 mocks/stubs。换句话说,行为相同的事物,但实际上在您的完全控制之下。
在你的情况下 SpeechRecognitionEngine
,即使它可能可用,对于单元测试来说也太麻烦了。 Who/what会说话吗?而且就算触发了事件,为什么要实例化一个真实的实例SpeechRecognitionEngine
?
查看 MSDN 的 SpeechRecognitionEngine
定义表明它没有实现接口,这意味着很难 mock/stub。
对于这种情况,您需要包装,换句话说,将 SpeechRecognitionEngine
封装到您自己的 class 中,它实现了您的接口。然后,您需要做的就是拥有您的接口的两个实现,一个具有真正的 SpeechRecognitionEngine
用于真实的语音识别,另一个具有 class 用于单元测试,它只是模仿您自己的回调,而不是使用 SpeechRecognized
事件。
您只需将一个实例换成另一个实例,您的代码将看不出有什么不同,因为它们实现的是单一接口。
如果你只是想模拟一个事件,你只需要调用一个事件处理器,因为这是一个方法。或者另一种方法,如果你不能创建一些 EventArgs
。但问题是您必须从 class 外部公开内部方法(例如将其标记为 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
.
微软已经想到了语音识别的仿真。这是 SpeechRecognitionEngine.EmulateRecognize Method
: