我有以下类和接口
public interface IService
{
Task<double> GetAccDetails(int personId);
}
public class Person
{
private int _personId;
private IService _service;
public Person(int personId, IService service)
{
_personId= personId;
_service = service;
}
public double Amount {get; set;}
public async void UpdateBanckingAcc()
{
Amount = await _service.GetAccDetails(_personId);
}
}
我正在尝试为它编写nunit测试:
[Test]
public async void Test1([Values(200)]int personId)
{
const double expectedResult = 20;
var serviceMock = new Mock<IAccountService>();
//Here I tried both options:
//serviceMock.Setup(s => s.GetAccDetails(It.Is<int>(id => id == personId)))
// .ReturnsAsync(() => expectedResult);
//And:
serviceMock.Setup(s=> s.GetAccDetails(It.Is<int>(id => id == personId)))
.Returns(() => Task.FromResult<double>(personId));
var person = new Person(personId, serviceMock.Object);
person.UpdateBanckingAcc();
double res = person.Amount;
Assert.AreEqual(expectedResult, res);
}
测试失败。由于一些奇怪的原因,我无法调试它 所以我在这里看到的问题是电话:
person.UpdateBanckingAcc();
应该是
await person.UpdateBanckingAcc();
但如果我使用await
关键字,则不喜欢。
请告知。
还有一个问题:对于我应该测试的异步方法的nunit测试,有什么特定的东西,比如任务状态测试等吗?
答案 0 :(得分:0)
此处的问题是,您的方法UpdateBankingAcc
的返回类型void
应该返回Task<T>
或Task
,因此您需要将其签名更改为重新命名Task
,如:
public async Task UpdateBanckingAcc()
{
Amount = await _service.GetAccDetails(_personId);
}
现在您需要将测试代码更改为:
await person.UpdateBanckingAcc();
double res = person.Amount;
Assert.AreEqual(expectedResult, res);
你永远不应该从异步方法返回void,除非它是UI控件事件,你可以阅读有关使用async的最佳实践并等待以下内容:
https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
http://www.tonicodes.net/blog/why-you-should-almost-never-write-void-asynchronous-methods/
答案 1 :(得分:0)
有一条简单的规则:async void
用于即发即弃行为,仅用于此目的。如果您需要async
方法,请将其返回类型更改为Task
,如@EhsanSajjad所述。这也与单元测试相对应:
public async Task UpdateBanckingAcc()
public async Task Test1([Values(200)]int personId)