2009-09-01 45 views
5

Sau khi mã hóa một phương pháp mở rộng (dựa trên GUI update when starting event handler class on separate thread?):Làm thế nào để kiểm tra phương thức UI thử nghiệm đơn vị đúng cách trên một chuỗi khác?

public static class ControlExtensions 
{ 
    public static TResult InvokeEx<TControl, TResult> (this TControl control, 
                 Func<TControl, TResult> func) 
     where TControl : Control 
    { 
     if (control.InvokeRequired) 
      return (TResult)control.Invoke (func, control); 

     return func (control); 
    } 
} 

Tôi đã cố gắng để đơn vị thử nghiệm phương pháp này cả hai từ một thread UI và một sợi bình thường và tôi dường như không thể để có thể đạt được cái đó.

Đây là mã đơn vị kiểm tra:

[Test] 
public void TestInvokeExWithMethodReturningResultOnOtherThread() 
{ 
    // Prepare 
    string result = string.Empty; 
    var form = new Form(); 
    var thread = new Thread (() => 
          { 
           result = form.InvokeEx (f => f.Text); 
          }); 

    // Execute 
    thread.Start(); 
    thread.Join (1000); 

    // Verify 
    Assert.That (result, Is.EqualTo ("Some label")); 
} 

Các đèo thử nghiệm nhưng nếu tôi đặt một breakpoint trong InvokeEx phương pháp (không phải là cuộc gọi) Tôi thấy rằng Control.InvokeRequired là sai dẫn đến phương thức func được gọi trực tiếp.

Hơn nữa, bây giờ thử nghiệm không thành công vì kết quả không được đặt.

Ngoài ra, khi bước qua mã, tôi thấy rằng phương thức func được thực hiện trên luồng khác (như mong đợi) chứ không phải trên luồng chính.

Có thể vì tôi không có chuỗi giao diện người dùng thực vì tôi đang thực hiện kiểm tra đơn vị? Làm thế nào tôi sẽ đạt được điều đó và tất cả các thông điệp bơm?

Trả lời

5

Tôi đã cố gắng điều khác nhau và tôi đã đưa ra như sau:

[Test] 
public void TestInvokeExWithMethodReturningResultOnOtherThread() 
{ 
    // Prepare 
    string result = string.Empty; 
    var form = new Form(); 
    var uiThread = new Thread (() => Application.Run (form)); 
    uiThread.SetApartmentState (ApartmentState.STA); 
    uiThread.Start(); 
    Thread.Sleep (100); 
    var thread = new Thread (() => result = form.InvokeEx (f => f.Text)); 

    // Execute 
    thread.Start(); 
    thread.Join(); 
    form.InvokeEx (f => f.Close()); 
    uiThread.Join(); 

    // Verify 
    Assert.That (result, Is.EqualTo ("Some label")); 
} 

này hiện đang làm việc một cách hoàn hảo.

Lưu ý rằng tôi phải thêm quá tải cho InvokeEx cho một phương thức void.

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