我正在编写一些代码,可以自动检测设备(在本例中为光谱仪)连接的串行端口。
我有自动检测部分工作,我正试图为显示检测进度,错误等的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。
- 不编译。
autoDetectMock.Setup
行有错误:Error 1 Delegate 'System.Action' does not take 1 arguments
。我在其他(非同步)测试中使用了相同的技术来访问传递的值。 - 这种方法会有效吗?如果我对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。
我相信,在你解决了这两个问题之后,它应该可以工作了。