Tại sao không thể nhận dạng các bài kiểm tra đơn vị “async void”?


79

async void Không thể chạy các bài kiểm tra đơn vị trong Visual Studio 2012:

[TestClass]
public class MyTestClass
{
    [TestMethod]
    public async void InvisibleMyTestMethod()
    {
        await Task.Delay(1000);
        Assert.IsTrue(true);
    }
}

Nếu tôi muốn kiểm tra đơn vị không đồng bộ, phương pháp kiểm tra phải trả về Tác vụ:

[TestMethod]
public async Task VisibleMyTestMethod()
{
    await Task.Delay(1000);
    Assert.IsTrue(true);
}

Tại sao nó như vậy? Không phải tôi nhất thiết phải có async voidphương pháp kiểm tra, tôi chỉ tò mò. Visual Studio 2012 không đưa ra cảnh báo cũng như lỗi khi bạn xây dựng một async voidphương pháp thử nghiệm mặc dù nó sẽ không thể chạy được ...

Câu trả lời:


83

async voidphương pháp nên được coi là "Fire and Forget" - không có cách nào để đợi chúng kết thúc. Nếu Visual Studio bắt đầu một trong những thử nghiệm này, nó sẽ không thể đợi thử nghiệm hoàn tất (đánh dấu là thành công) hoặc mắc bất kỳ ngoại lệ nào được nêu ra.

Với một async Task, người gọi có thể đợi quá trình thực thi hoàn tất và bẫy bất kỳ ngoại lệ nào được nêu ra trong khi nó chạy.

Xem câu trả lời này để thảo luận hơn về async voidvs async Task.


3
Đây không phải là sự thật. NUnit có hỗ trợ async voidcác bài kiểm tra và cách thức và lý do hỗ trợ nó được nêu chi tiết ở một mức độ nào đó trong liên kết này . Xem câu trả lời bên dưới.
Anupam

21

Đó chỉ là vì MSTest không hỗ trợ async voidcác bài kiểm tra đơn vị. Có thể làm như vậy bằng cách giới thiệu một ngữ cảnh mà chúng có thể thực thi.

MSTest không hỗ trợ điều này, có thể do Microsoft quyết định rằng nó có quá nhiều thay đổi đối với các thử nghiệm hiện có (có thể các thử nghiệm hiện tại sẽ bế tắc nếu chúng được đưa ra một bối cảnh không mong muốn).

Không có cảnh báo / lỗi trình biên dịch vì đó là mã C # hoàn toàn hợp lệ. Lý do duy nhất mà nó không hoạt động là do khuôn khổ kiểm tra đơn vị (tức là, tôi tin rằng xUnit có hỗ trợ async voidkiểm tra) và việc phân tách các mối quan tâm đối với trình biên dịch C # để xem xét các thuộc tính của bạn, xác định bạn sẽ là một vi phạm hoàn toàn. đang sử dụng MSTest và quyết định rằng bạn thực sự không muốn sử dụng async void.


1
Trong lần triển khai đầu tiên (Visual Studio Preview), thử nghiệm sẽ được biên dịch lại và "chạy". Vấn đề là phương pháp sẽ kết thúc trong lần chờ đợi đầu tiên và đó là kết quả của thử nghiệm.
Paulo Morgado

21

Tôi nhận thấy trong VS2015 rằng bất kỳ phương pháp Kiểm tra nào được trang trí bằng không đồng bộ sẽ không hiển thị trong Trình khám phá thử nghiệm. Tôi đã kết thúc việc xóa từ khóa async và thay thế cuộc gọi await trong bài kiểm tra bằng một task.Wait () và thực hiện các thao tác trên task.Result.

Có vẻ như đang hoạt động tốt. Chưa thử nó với thử nghiệm ngoại lệ.

var task = TheMethodIWantToTestAsync(someValue);
task.Wait();
var response = task.Result;

Assert.IsNotNull(response);
Assert.IsTrue(response.somevalue);

3
Đừng nghĩ rằng nó cần gọi task.Wait () khi gọi task, nó sẽ tự động gọi task.Wait () nếu tác vụ chưa hoàn thành.
stt106,
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.