【发布时间】:2016-09-08 15:41:14
【问题描述】:
我有一段生产代码,其中必须完成一些长期任务才能完成其他工作(参见下面的示例)。我可以测试调用顺序,但 不是 await (示例中缺少)。我必须做些什么来测试这个?
using System.Threading.Tasks;
using Moq;
using NUnit.Framework;
namespace TestingCallsAwaitedDemo
{
public interface IFoo
{
Task DoThisFirst();
}
public interface IBar
{
void ThenDoThis();
}
public class Demo
{
private readonly IFoo _foo;
private readonly IBar _bar;
public Demo(IFoo foo, IBar bar)
{
_bar = bar;
_foo = foo;
}
public async Task DoSomething()
{
_foo.DoThisFirst(); // The await is missing. How do I force its presence with a test?
_bar.ThenDoThis();
}
}
[TestFixture]
public class DemoTests
{
private Demo classUnderTest;
private Mock<IFoo> fooMock;
private Mock<IBar> barMock;
[SetUp]
public void Setup()
{
fooMock = new Mock<IFoo>();
barMock = new Mock<IBar>();
classUnderTest = new Demo(fooMock.Object, barMock.Object);
}
[Test]
public async Task MustFinishDoThisFirstBeforeCallingThenDoThis()
{
var callOrder = string.Empty;
fooMock.Setup(v => v.DoThisFirst())
.Callback(() => callOrder += "DoThisFirst >> ");
barMock.Setup(v => v.ThenDoThis())
.Callback(() => callOrder += "ThenDoThis >> ");
await classUnderTest.DoSomething();
Assert.AreEqual(
"DoThisFirst >> ThenDoThis >> ",
callOrder);
//How do I test the missing await?
}
}
}
这是一个解决方案。感谢@dvorn
[Test]
public async Task MustFinishDoThisFirstBeforeCallingThenDoThis()
{
var tcs = new TaskCompletionSource<bool>();
fooMock.Setup(v => v.DoThisFirst()).Returns(tcs.Task);
var task = classUnderTest.DoSomething();
Assert.IsFalse(task.IsCompleted, "Did not await 'DoThisFirst'");
fooMock.Verify(f => f.DoThisFirst(), Times.Once);
barMock.Verify(b => b.ThenDoThis(), Times.Never);
tcs.SetResult(true);
await task;
Assert.IsTrue(task.IsCompleted);
fooMock.Verify(f => f.DoThisFirst(), Times.Once);
barMock.Verify(b => b.ThenDoThis(), Times.Once);
}
【问题讨论】:
-
您应该等待 SetResult 和断言 IsCompleted 之间的任务。否则不保证成功。
-
我一开始有那个,但它似乎并没有什么不同。无论如何,我认为你是对的,因为它有时可能会失败。我会纠正我的例子。
-
通常 SetResult 同步运行延续,它会工作:stackoverflow.com/questions/12693046/…。但是,明确说明您的意图是明智的。你永远不知道几年后其他开发人员将如何修改这段代码......
标签: c# unit-testing async-await nunit moq