我有简单的类,使用这样的简单方法:
partial class SimpleClass
{
private readonly ISimpleManager _simpleManager;
public SimpleClass(ISimpleManager simpleManager)
{
_simpleManager = simpleManager;
}
public async void SimpleMethod()
{
IsInProgress = true;
DoSomeWork();
Task<int> hardWork0Task = _simpleManager.DoHardWork0Async();
Task<int> hardWork1Task = _simpleManager.DoHardWork1Async();
DoIndependentWork();
int hardWork0Result = await hardWork0Task.ConfigureAwait(false);
DoDependentWork(hardWork0Result);
int hardWork1Result = await hardWork1Task.ConfigureAwait(false);
DoDependentWork(hardWork1Result);
IsInProgress = false;
}
}
假设属性IsInProgress
只是bool
属性,通知GUI关于其状态以允许刷新进度条。 DoSomeWork
,DoDependentWork
和DoIndependentWork
是使用或不使用辛勤工作结果的一些方法。
ISimpleManager
是您可以想象的最简单的界面:
interface ISimpleManager
{
Task<int> DoHardWork0Async();
Task<int> DoHardWork1Async();
}
我必须使用Moq和NUnit编写一些单元测试。如何为这种情况编写单元测试?我想检查在与GUI异步运行的整个代码期间IsInProgress
属性的状态是否未更改为false。是否有意义?可能吗?如果我的async
方法返回Task
或通用Task<T>
怎么办?如果我为true
配置等待
答案 0 :(得分:1)
您只需要控制ISimpleManager
任务的完成时间。根据Ilya的回答,您可以使用SemaphoreSlim
执行此操作,也可以直接使用TaskCompletionSource<T>
。我通常更喜欢TaskCompletionSource<T>
,因为它更简单;但是,SemaphoreSlim
实例可以重复使用,而TaskCompletionSource<T>
只能触发一次。
另外,除非方法是事件处理程序,否则应避免使用async void
。 不应该是&#34;默认&#34;任何形式 - 默认应该是返回Task
,除非您绝对不能。因此,在此示例中,SimpleMethod
肯定会返回Task
。
以下是使用TCS的样子:
async Task MyTestMethod()
{
// Set up the mock object
var tcs0 = new TaskCompletionSource<int>();
var tcs1 = new TaskCompletionSource<int>();
var stub = new Mock<ISimpleManager>();
stub.Setup(x => x.DoHardWork0Async()).Returns(tcs0.Task);
stub.Setup(x => x.DoHardWork1Async()).Returns(tcs1.Task);
var sut = new SimpleClass(stub.Object);
var task = sut.SimpleMethod();
Assert.True(sut.InProgress);
tcs0.SetResult(7);
Assert.True(sut.InProgress);
tcs1.SetResult(13);
await task;
Assert.False(sut.InProgress);
}
答案 1 :(得分:0)
以下是如何对IsInProgress
设置正确的单元测试:
创建一个等待的信号量:
var sem = new SemaphoreSlim(1);
使用以下实现创建存根ISimpleManager
:
async Task<int> DoHardWork0Async() {
await sem.WaitAsync();
return 0;
}
致电SimpleMethod
。在DoHardWork0Async
验证IsInProgress
作为清理步骤,释放信号量:
sem.Release();