使用NUnit和Moq测试等待调用

本文关键字:等待 调用 测试 Moq NUnit 使用 | 更新日期: 2023-09-27 18:06:25

我有一段生产代码,其中一些长时间的任务必须在完成其他任务之前完成(参见下面的示例)。我能够测试调用顺序,但不能测试 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);
}

使用NUnit和Moq测试等待调用

TaskCompletionSource<bool> tcs;

设置fooomock返回tcs。任务

var task = classUnderTest.DoSomething();

断言任务未完成。

tcs.SetResult(真正)。

现在等待任务