2016-12-20 172 views
2

我有下面的類和接口NUnit的測試失敗,在C#

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

你使用的是什麼版本的NUnit?最近的版本應該指出異步無效測試是無效的。 – Charlie

回答

0

這裏的問題是,你的方法UpdateBankingAcc有返回類型void應返回一個Task<T>Task,所以你需要改變它的簽名reutrn一個Task像:

public async Task UpdateBanckingAcc() 
{ 
    Amount = await _service.GetAccDetails(_personId); 
} 

,現在你需要改變你的測試代碼爲:

await person.UpdateBanckingAcc(); 

double res = person.Amount; 
Assert.AreEqual(expectedResult, res); 

你應該永遠不會從異步方法返回void,除非它是UI控件的事件,你可以閱讀有關的是使用異步的ST實踐和等候在以下幾點:

https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

http://www.tonicodes.net/blog/why-you-should-almost-never-write-void-asynchronous-methods/

async/await - when to return a Task vs void?

+0

請參閱我最近的評論 –

+0

您如何建議進行更改 - fales。 –

0

有一個簡單的規則:async void用於發射後不管行爲,只爲這個。如果您需要async方法,請將其返回類型更改爲Task,如@EhsanSajjad所述。這也對應於單元測試:

public async Task UpdateBanckingAcc() 

public async Task Test1([Values(200)]int personId)