验证从异步调用报告的进度将在单元测试中正确报告

本文关键字:报告 单元测试 异步 调用 验证 | 更新日期: 2023-09-27 18:02:05

我正在编写一些代码,可以自动检测设备(在本例中为光谱仪)连接的串行端口。

我有自动检测部分工作,我正试图为显示检测进度,错误等的ViewModel编写测试。

下面是执行实际检测的代码的接口。

public interface IAutoDetector
{
  Task DetectSpectrometerAsync(IProgress<int> progress);
  bool IsConnected { get; set; }
  string SelectedSerialPort { get; set; }
}

这是使用IAutoDetector检测光谱仪的ViewModel

public class AutoDetectViewModel : Screen
{
   private IAutoDetector autoDetect;
   private int autoDetectionProgress;
   public int AutoDetectionProgress
   {
      get { return autoDetectionProgress; }
      private set
      {
         autoDetectionProgress = value;
         NotifyOfPropertyChange();
      }
   }
   [ImportingConstructor]
   public AutoDetectViewModel(IAutoDetector autoDetect)
   {
      this.autoDetect = autoDetect;
   }
   public async Task AutoDetectSpectrometer()
   {
      Progress<int> progressReporter = new Progress<int>(ProgressReported);
      await autoDetect.DetectSpectrometerAsync(progressReporter);
   }
   private void ProgressReported(int progress)
   {
      AutoDetectionProgress = progress;
   }
}

我正试图编写一个测试,验证从IAutoDetector报告的进度更新AutoDetectionViewModel中的AutoDetectionProgress属性。

这是我当前(不工作)的测试:

[TestMethod]
public async Task DetectingSpectrometerUpdatesTheProgress()
{
   Mock<IAutoDetector> autoDetectMock = new Mock<IAutoDetector>();
   AutoDetectViewModel viewModel = new AutoDetectViewModel(autoDetectMock.Object);
   IProgress<int> progressReporter = null;
   autoDetectMock.Setup(s => s.DetectSpectrometerAsync(It.IsAny<IProgress<int>>()))
      .Callback((prog) => { progressReporter = prog; });
   await viewModel.AutoDetectSpectrometer();
   progressReporter.Report(10);
   Assert.AreEqual(10, viewModel.AutoDetectionProgress);
}

我想做的是抓住传递给autoDetect.DetectSpectrometerAsync(progressReporter)IProgress<T>,告诉IProgress<T>报告10的进度,然后确保viewModel中的AutoDetectionProgress也是10。

然而,这段代码有两个问题:
  1. 不编译。autoDetectMock.Setup行有错误:Error 1 Delegate 'System.Action' does not take 1 arguments。我在其他(非同步)测试中使用了相同的技术来访问传递的值。
  2. 这种方法会有效吗?如果我对async的理解是正确的,调用await viewModel.AutoDetectSpectrometer();将在调用progressReporter.Report(10);之前等待调用完成,这不会有任何影响,因为AutoDetectSpectrometer()调用已经返回。

验证从异步调用报告的进度将在单元测试中正确报告

必须指定回调的返回类型;编译器将无法为您确定。

autoDetectMock
      .Setup(s => s.DetectSpectrometerAsync(It.IsAny<IProgress<int>>()))
      .Callback((prog) => { progressReporter = prog; }); // what you have
应该

autoDetectMock
      .Setup(s => s.DetectSpectrometerAsync(It.IsAny<IProgress<int>>()))
      .Callback<IProgress<int>>((prog) => { progressReporter = prog; }); 

你也没有从你的安装程序返回一个任务,所以这也会失败。你需要返回一个Task。

我相信,在你解决了这两个问题之后,它应该可以工作了。