如果任务后面跟着task.start(),如何编写单元测试?

发布于 2025-01-20 01:13:56 字数 1704 浏览 2 评论 0原文

在程序中,我们有:

var task1 = some task;
task1.start()

如果模拟任务结果在单位测试中,则在调用start()之前立即通过模拟机制返回结果,并且提高“开始”的任务不可能在完成的任务上调用”例外。

如何解决该问题并构成有效的单元测试?

在此处粘贴简化的示例代码,以清楚起见,这会产生上述例外:

namespace TestTaskStart
{
    public class TestMethods : ITestMethods
    {
        public async Task<int> AlwaysReturnOne(int number)
        {
            return await Task.FromResult(1);
        }
    }
}

namespace TestTaskStart {
    public class TestInvoker
    {
        private ITestMethods testMethods;

        public TestInvoker(ITestMethods testMethods)
        {
            this.testMethods = testMethods;
        }

        public async Task<int> GetANumberWrapperTask(int number)
        {
            // just an exmple of one tasks to be called
            var task = this.testMethods.AlwaysReturnOne(number);
            task.Start();
            Task.WaitAll(task);

            return task.Result;
        }
    }
}

namespace TestTaskStart {
    [TestClass]
    public class UnitTests
    {
        ITestMethods numberGetter;
        TestInvoker testInvoker;

        [TestInitialize]
        public void Setup()
        {
            this.numberGetter = Substitute.For<ITestMethods>();
            this.testInvoker = new TestInvoker(this.numberGetter);
        }

        [TestMethod]
        public void TestGetANumberWrapper()
        {
            this.MockAlwaysReturnOneResult();
            var result = testInvoker.GetANumberWrapperTask(5).Result;
        }

        private void MockAlwaysReturnOneResult()
        {
            this.numberGetter.AlwaysReturnOne(Arg.Any<int>()).Returns(1);
        }
    }
}

In program, we have:

var task1 = some task;
task1.start()

If mock the task result in unit test, the result is returned by mock mechanism immediately before calling the start(), and raise "Start may not be called on a task that has completed" exception.

How to address that issue and compose a valid unit test?

Paste a simplified sample code here for clarity, which produces the above exception:

namespace TestTaskStart
{
    public class TestMethods : ITestMethods
    {
        public async Task<int> AlwaysReturnOne(int number)
        {
            return await Task.FromResult(1);
        }
    }
}

namespace TestTaskStart {
    public class TestInvoker
    {
        private ITestMethods testMethods;

        public TestInvoker(ITestMethods testMethods)
        {
            this.testMethods = testMethods;
        }

        public async Task<int> GetANumberWrapperTask(int number)
        {
            // just an exmple of one tasks to be called
            var task = this.testMethods.AlwaysReturnOne(number);
            task.Start();
            Task.WaitAll(task);

            return task.Result;
        }
    }
}

namespace TestTaskStart {
    [TestClass]
    public class UnitTests
    {
        ITestMethods numberGetter;
        TestInvoker testInvoker;

        [TestInitialize]
        public void Setup()
        {
            this.numberGetter = Substitute.For<ITestMethods>();
            this.testInvoker = new TestInvoker(this.numberGetter);
        }

        [TestMethod]
        public void TestGetANumberWrapper()
        {
            this.MockAlwaysReturnOneResult();
            var result = testInvoker.GetANumberWrapperTask(5).Result;
        }

        private void MockAlwaysReturnOneResult()
        {
            this.numberGetter.AlwaysReturnOne(Arg.Any<int>()).Returns(1);
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你与昨日 2025-01-27 01:13:56

Task.Start 方法只能在“冷”任务上调用,换句话说,在尚未启动的任务上调用。此类任务只能使用 Task 构造函数创建。通过调用使用 async 关键字实现的异步方法创建的任务是“热”任务,换句话说,它们在创建时就已启动。来自文档:

例外
InvalidOperationException
Task 未处于要启动的有效状态。它可能已经启动、执行或取消,或者可能是以不支持直接调度的方式创建的。

这也是一本很好的读物: 任务概览,第 10 部分:Promise 任务

The Task.Start method can only be called on "cold" tasks, in other words on tasks that have not been started yet. Such tasks can only be created with the Task constructor. Tasks created by invoking asynchronous methods implemented with the async keyword are "hot", in other words they are already started upon creation. From the docs:

Exceptions
InvalidOperationException
The Task is not in a valid state to be started. It may have already been started, executed, or canceled, or it may have been created in a manner that doesn't support direct scheduling.

This is also a good reading: A Tour of Task, Part 10: Promise Tasks

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文