有没有办法对异步方法进行单元测试?
我在 .NET 平台上使用 Xunit 和 NMock。 我正在测试一个表示模型,其中方法是异步的。 该方法创建一个异步任务并执行它,以便该方法立即返回,并且我需要检查的状态尚未准备好。
我可以在完成时设置一个标志而不修改 SUT,但这意味着我必须在 while 循环中继续检查该标志,例如,可能会超时。
我有什么选择?
I am using Xunit and NMock on .NET platform.
I am testing a presentation model where a method is asynchronous.
The method creates an async task and executes it so the method returns immediately and the state I need to check aren't ready yet.
I can set a flag upon finish without modifying the SUT but that would mean I would have to keep checking the flag in a while loop for example, with perhaps timeout.
What are my options?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
只是认为您可能需要对此进行更新,因为#1 答案实际上是推荐一种较旧的模式来解决此问题。
在 .net 4.5 + xUnit 1.9 或更高版本中,您可以简单地返回一个任务,并可以选择使用测试中的 async 关键字让 xunit 等待测试异步完成。
请参阅有关 xUnit.net 1.9 的文章
Just thought you might want an update on this since the #1 answer is actually recommending an older pattern to solve this problem.
In .net 4.5 + xUnit 1.9 or higher you can simply return a Task and optionally use the async keyword from your test to have xunit wait for the test to complete asynchronously.
See this article on xUnit.net 1.9
您的对象是否具有异步方法完成的任何类型的信号,例如事件? 如果是这种情况,您可以使用以下方法:
Does your object feature any sort of signal that the asynchronous method is finished, such as an event? If that is the case, you can use the following approach:
我的首选方法是模拟并注入实际的线程机制,以便在测试时它不是异步的。 有时这是不可能的(如果方法的线程是框架的一部分,或者不在您的控制之下)。
如果您无法控制线程创建,则等待线程以某种方式完成,无论是 while 循环还是只是定时等待线程应该花费的时间,如果状态不存在,则测试失败无论如何花了太长时间。
My preferred method is to mock out and inject the actual threading mechanism so that under test it is not asynchronous. Some times that is not possible (if the threading of the method is part of the framework, or otherwise not under your control).
If you can't control thread creation, then waiting for the thread to finish in some way, either a while loop or just a timed wait for however long the thread is supposed to take and failing the test if the state is not there since it took too long anyway.
查看我关于 Silverlight 应用程序单元测试的文章
http://www.codeproject.com/KB /silverlight/Ag3DemoLOB.aspx
有一个对异步调用 WCF 服务的方法进行单元测试的示例...
check out my article on unit testing Silverlight applications
http://www.codeproject.com/KB/silverlight/Ag3DemoLOB.aspx
There is an example of unit testing a method that calls a WCF service asynchronously...
使用 NSubtitute 和 XUnit 进行异步测试实际上非常简单:
调用者:
因为异步方法仅返回任务,所以使用 NSubstitute 模拟 DoSomething() 所需要做的就是使用 Task.FromResult()。 然后调用代码返回一个任务,它仍然可以等待并返回整数结果。
因此,使用 NSubstitute 模拟它看起来像这样:
通过使测试异步添加一点额外的内容:
在测试异步方法时,后者比前者更受青睐。
归功于:https://www.garethrepton.com/Unit-Testing-async-methods/#:~:text=因为%20Async%20methods%20just%20return%20tasks%2C%20all%20you,所以%20mocking%20it%20用%20NSubstitute%20looks%20like%20this%3A
Async Tests with NSubtitute and XUnit are actually pretty straight forward:
called by:
Because Async methods just return tasks, all you need to do to mock DoSomething() with NSubstitute is use Task.FromResult(). Then the calling code gets a task back that it can still await and get back the integer result.
So mocking it with NSubstitute looks like this:
Adding a little extra by making the test async:
The latter is favoured over the former when testing async methods.
Credit to: https://www.garethrepton.com/Unit-Testing-async-methods/#:~:text=Because%20Async%20methods%20just%20return%20tasks%2C%20all%20you,So%20mocking%20it%20with%20NSubstitute%20looks%20like%20this%3A