【发布时间】:2015-11-10 06:49:58
【问题描述】:
我有一个带有异步任务的 viewModel。我现在不知道如何测试它。
public class MyViewModel : BindableBase
{
public MyViewModel()
{
this.PropertyChanged += MyViewModel_PropertyChanged;
}
private void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
Action action = async () => await DoSomething();
action();
}
public const string BeforeKey = "before";
public const string AfterKey = "After";
public string Status { get; private set; } = BeforeKey;
public async Task DoSomething()
{
await Task.Delay(3000);
Status = AfterKey;
}
string bindagleProp;
public string BindagleProp
{
get { return bindagleProp; }
set { SetProperty(ref bindagleProp, value); }
}
}
这是我的测试:
[TestMethod]
public async Task TestMyViewModel()
{
MyViewModel viewModel = new MyViewModel();
Assert.AreEqual(viewModel.Status, MyViewModel.BeforeKey, "before check");
viewModel.BindagleProp = "abc";
Assert.AreEqual(viewModel.Status, MyViewModel.AfterKey, "after check");
}
测试失败,因为它没有等待任务完成。
我不想在单元测试中使用 Task.Delay,因为它不安全。 DoSomething 方法可以有未知的持续时间。
感谢您的帮助。
编辑:
事实上,这个问题并不特定于 MVVM,而是任何异步事件处理程序。 例如:
// class with some logic, can be UI or whatever.
public class MyClassA
{
Size size;
public Size Size
{
get { return size; }
set
{
size = value;
SizeChanged?.Invoke(this, EventArgs.Empty);
}
}
public event EventHandler SizeChanged;
}
// this class uses the MyClassA class.
public class MyCunsomerClass
{
readonly MyClassA myClassA = new MyClassA();
public MyCunsomerClass()
{
myClassA.SizeChanged += MyClassA_SizeChanged;
}
public string Status { get; private set; } = "BEFORE";
private async void MyClassA_SizeChanged(object sender, EventArgs e)
{
await LongRunningTaskAsync();
Status = "AFTER";
}
public async Task LongRunningTaskAsync()
{
await Task.Delay(3000);
///await XYZ....;
}
public void SetSize()
{
myClassA.Size = new Size(20, 30);
}
}
现在,我想测试一下:
[TestMethod]
public void TestMyClass()
{
var cunsomerClass = new MyCunsomerClass();
cunsomerClass.SetSize();
Assert.AreEqual(cunsomerClass.Status, "AFTER");
}
测试失败。
【问题讨论】:
-
完成的代码中是否会有
await Task.Delay(3000);,或者你是用它来模拟一个长时间运行的任务? -
仅供模拟使用。真正的方法可以做任何长时间运行的任务。
-
这可能已经有答案了here
-
正如 Netscape 所指出的,你做错了。这整个讨论毫无意义。 OP 显然不知道事件如何工作或异步工作流应该如何工作。他需要先了解这些,然后才能讨论任何有关测试的内容。就目前而言,恕我直言,这个问题没有希望
-
@Maverik .Result 和 .Wait() 是黑客。不是解决方案。通常不鼓励使用它们。
标签: c# unit-testing asynchronous mvvm async-await