2014-07-18 24 views
5

Tôi ngạc nhiên breakpoint của tôi sau khi await ing một phương pháp async đó là trên một dòng tham chiếu đến chờ đợi Task<T> không bao giờ nhấn:Làm thế nào để sử dụng điểm ngắt sau khi chờ kiểm tra đơn vị?

[Test] 
    public async void GetSomethingTest() 
    { 
     var service = SimpleIoc.Default.GetInstance<IService>(); 
     var result = await service.TryGetSomethingAsync(20); 
     Assert.IsTrue(result.IsSuccess); 
     Assert.IsNotNull(result.ReturnValue); 
    } 

Đưa một breakpoint trên dòng đầu tiên Assert không bao giờ trúng nhưng các thử nghiệm đi.

Làm thế nào để tôi nghỉ ngơi khi chờ trở lại?

CẬP NHẬT: Tôi đoán đó là vì khuôn khổ kiểm tra không phải là await ing invocation của phương pháp kiểm tra, tôi đang sử dụng NUnit 2.6.3 và rằng tuyên bố async hỗ trợ, tuy nhiên cho dù đó đòi hỏi phải phá vỡ sau một await như tôi đang cố gắng làm, tôi không chắc chắn ...

+1

Thay đổi phương thức thử nghiệm của bạn từ khoảng trống không đồng bộ thành không đồng bộ Task – Neel

+0

@Cảm thấy điều đó không hữu ích: ( – markmnl

+1

Tôi đã gặp phải tất cả các vấn đề với kiểm tra đơn vị gỡ lỗi. Nếu nó không hoạt động theo cách bạn muốn, hãy sao chép thử nghiệm của bạn – nvoigt

Trả lời

10

Vấn đề là phương pháp của bạn là async void. Điều đó có ngữ nghĩa cháy và quên.

Về mặt lý thuyết những gì phương pháp bạn đang làm với async - sử dụng await trông như thế này:

[Test] 
public void GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    service.TryGetSomethingAsync(20).ContinueWith(t => 
    { 
     var result = t.Result; 
     Assert.IsTrue(result.IsSuccess); 
     Assert.IsNotNull(result.ReturnValue); 
    }); 
} 

Bây giờ nó phải rõ ràng vấn đề là gì. Phương pháp thử nghiệm của bạn ngay lập tức trả lại ngay sau khi TryGetSomethingAsync trả về Task của nó. Vì vậy, kiểm tra ngay lập tức kết thúc. Vì không có ngoại lệ nào được ném ra, nó là một thành công.

Nếu khuôn khổ thử nghiệm của bạn hỗ trợ Task kiểm tra -returning, bạn có thể sửa chữa bài kiểm tra của bạn để làm những gì bạn muốn bằng cách đơn giản thay đổi kiểu trả về của nó để Task thay vì void.

[Test] 
public async Task GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    var result = await service.TryGetSomethingAsync(20); 
    Assert.IsTrue(result.IsSuccess); 
    Assert.IsNotNull(result.ReturnValue); 
} 

Điều này sẽ dịch khái niệm như sau.

[Test] 
public Task GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    return service.TryGetSomethingAsync(20).ContinueWith(t => 
    { 
     var result = t.Result; 
     Assert.IsTrue(result.IsSuccess); 
     Assert.IsNotNull(result.ReturnValue); 
    }); 
} 

Thông báo như thế nào Task tiếp tục được trả lại, vì vậy mà khuôn khổ kiểm tra bây giờ có thể chờ đợi vào nó, đảm bảo rằng tất cả các mã của thử nghiệm có thời gian để chạy trước khi thử nghiệm được coi là đã hoàn thành.

(Về mặt kỹ thuật, khung cũng có thể hoạt động trong trường hợp async void, nhưng tôi không biết lý do nào sẽ là một tính năng tốt, vì vậy tôi mong đợi hầu hết không xử lý được.)

Nếu khung kiểm tra của bạn không hỗ trợ các bài kiểm tra Trả lại tác vụ, bạn có thể sửa bài kiểm tra của mình bằng cách sử dụng .Result thay vì await.

[Test] 
public void GetSomethingTest() 
{ 
    var service = SimpleIoc.Default.GetInstance<IService>(); 
    var result = service.TryGetSomethingAsync(20).Result; 
    Assert.IsTrue(result.IsSuccess); 
    Assert.IsNotNull(result.ReturnValue); 
} 

này chỉ đơn giản là sẽ chặn các thread hiện hành cho đến khi Task trả về bởi TryGetSomethingAsync được hoàn tất.

+0

Chuyển sang MSTest và trả lại 'Task' đã giải quyết được vấn đề của tôi, nhưng nhờ câu trả lời chi tiết, tôi chắc chắn nó sẽ giúp ích cho bạn! – markmnl

Các vấn đề liên quan