Skip to main content
 首页 » 编程设计

c#之使用 ManualResetEvent 锁定测试对 NAudio 进行单元测试

2024年02月20日30www_RR

好吧,我正在尝试针对我为录音 session 创建的包装器对 NAudio 进行单元测试,这是启动和停止录音 session 的代码......

public void StartRecording(string claimNo, string ip_no, string ip_name) 
{ 
    if (this.IsRecording) 
    { 
        return; 
    } 
 
    this.Recordings.Add(new RecordingTrack(claimNo, ip_no, ip_name)); 
    if (this.MicrophoneLevel == default(float)) 
    { 
        this.MicrophoneLevel = .75f; 
    } 
 
    _aggregator.Reset(); 
 
    _input = new WaveIn(); 
    _input.WaveFormat = _waveFormat; 
 
    _input.DataAvailable += (s, args) => 
        { 
            _writer.Write(args.Buffer, 0, args.BytesRecorded); 
            byte[] buffer = args.Buffer; 
            for (int index = 0; index < args.BytesRecorded; index += 2) 
            { 
                short sample = (short)((buffer[index + 1] << 8) | buffer[index + 0]); 
                float sample32 = sample / 32768f; 
                _aggregator.Add(sample32); 
            } 
 
            if (this.DataAvailable != null) 
            { 
                this.DataAvailable(s, args); 
            } 
 
            if (!this.IsRecording) 
            { 
                _writer.Close(); 
                _writer.Dispose(); 
                _writer = null; 
            } 
        }; 
    _input.RecordingStopped += (s, args) => 
        { 
            _input.Dispose(); 
            _input = null; 
 
            if (this.RecordingStopped != null) 
            { 
                this.RecordingStopped(s, args); 
            } 
        }; 
 
    _writer = new WaveFileWriter(this.CurrentRecording.FileName, _input.WaveFormat); 
 
    _input.StartRecording(); 
    this.IsRecording = true; 
} 
 
public void StopRecording() 
{ 
    if (!this.IsRecording) 
    { 
        return; 
    } 
 
    this.CurrentRecording.Stop(); 
 
    this.IsRecording = false; 
    _input.StopRecording(); 
} 

...下面是我的单元测试。我正在使用 ManualResetEvent 断言事件被触发的成功,它是这样声明的......

private ManualResetEvent _eventRaised = new ManualResetEvent(false); 

...然而,问题是下面的测试只是简单地锁定并且事件永远不会被触发。 您能否确认问题是 WaitOne 不允许事件触发,因为它锁定了同一个线程?

bool success = false; 
_eventRaised.Reset(); 
 
var target = new RecordingSession(); 
target.StartRecording("1", "01", "Test Name"); 
 
target.RecordingStopped += (s, args) => 
    { 
        success = (target.CurrentRecording.Duration.TotalSeconds > 4); 
        _eventRaised.Set(); 
    }; 
 
Thread.Sleep(4000); 
target.StopRecording(); 
 
_eventRaised.WaitOne(); 
 
Assert.IsTrue(success); 

如果是这样,你能帮我做这个测试吗?我需要一些启发。

我已经多次使用 ManualResetEvent 来测试其他类上的事件并且它有效,但这里有些不同。

请您参考如下方法:

您永远不会收到事件,因为 WaveIn 的默认构造函数使用窗口回调,并且您没有在 GUI 线程上运行单元测试。您应该使用 WaveInEvent 而不是在非 gui 线程上工作。在最新的 NAudio 代码中,应抛出 InvalidOperationException 以防止您犯此错误。