2013-03-26 28 views
5

Tôi không chắc chắn nên bắt đầu từ đâu nhưng hãy để tôi cung cấp cho bạn một ý tưởng ngắn gọn về vị trí của tôi và những gì tôi muốn đạt được. Tôi khá mới để thử nghiệm đơn vị trên MVVM và gặp khó khăn trong việc kiểm tra các lệnh mà tôi tiếp xúc bằng cách sử dụng các thuộc tính lệnh ủy quyền PRISM. Lệnh ủy quyền của tôi gọi phương thức không đồng bộ phải đợi để tôi có thể nhận được kết quả thực tế. Dưới đây là một phương pháp asyc được gọi bằng phương pháp mà tôi muốn thử nghiệm.Cách kiểm tra đơn vị một ViewModel với phương thức async.

async void GetTasksAsync() 
     { 
      this.SimpleTasks.Clear(); 
      Func<IList<ISimpleTask>> taskAction =() => 
       { 
        var result = this.dataService.GetTasks(); 
        if (token.IsCancellationRequested) 
         return null; 
        return result; 
       }; 
      IsBusyTreeView = true; 

      Task<IList<ISimpleTask>> getTasksTask = Task<IList<ISimpleTask>>.Factory.StartNew(taskAction, token); 
      var l = await getTasksTask;   // waits for getTasksTask 


      if (l != null) 
      { 
       foreach (ISimpleTask t in l) 
       { 
        this.SimpleTasks.Add(t); // adds to ViewModel.SimpleTask 
       } 
      } 
     } 

cũng ở đây là các lệnh trong VM của tôi mà các cuộc gọi phương pháp async trên

this.GetTasksCommand = new DelegateCommand(this.GetTasks); 
     void GetTasks() 
     { 
       GetTasksAsync(); 
     } 

và bây giờ Phương pháp thử nghiệm của tôi đi như thế

[TestMethod] 
     public void Command_Test_GetTasksCommand() 
     { 
      MyViewModel.GetTaskCommand.Execute(); // this should populate ViewModel.SimpleTask 
      Assert.IsTrue(MyBiewModel.SimpleTask != null) 
     } 

Hiện nay những gì tôi nhận được là của tôi ViewModel.SimpleTask = null điều này là bởi vì nó không chờ cho phương thức async kết thúc. Tôi hiểu có một số chủ đề liên quan đến điều này đã có trong ngăn xếp tràn nhưng tôi không thể tìm thấy một cái gì đó liên quan đến DelegateCommands của tôi.

Trả lời

9

Phương thức của bạn GetTasksAsync sẽ trả lại một Tác vụ để bạn thực sự có thể đợi nó.

Tôi khuyên bạn nên this series trên Channel9, đặc biệt là this episode giải thích sự cố của bạn.

Chỉ cần làm rõ: Đơn giản chỉ cần thay đổi chữ ký của GetTasksAsync để

Task GetTasksAsync(); 

cho phép bạn làm điều này:

var t = GetAsync(); 
t.Wait(); 
Assert(...); 

Trong trường hợp bạn thực sự muốn kiểm tra lệnh trong các thử nghiệm đơn vị của bạn và không phải là phương thức thực sự được gọi bằng lệnh, bạn có thể sử dụng trường trong ViewModel để lưu trữ nhiệm vụ đang chờ (không sạch) hoặc thay thế DelegateCommand của bạn bằng cách mô tả trong bài đăng này: Awaitable DelegateCommand

Cập nhật: Ngoài bài đăng trên blog và xem xét bạn đang sử dụng PRISM, bạn nên xem một số Project Kona từ cùng một nhóm với PRISM. Họ thực sự đã triển khai DelegateCommand to support AsyncHandlers

+3

Hoặc thậm chí tốt hơn, điều này cho phép bạn sử dụng thử nghiệm đơn vị 'async Task' và thực hiện' đang chờ GetTasksAsync() '. –

+0

Cảm ơn câu trả lời.Tuy nhiên, điều này GetTasksAsync() là một phương pháp riêng trong ViewModel của tôi và không muốn phơi bày với bất kỳ đối tượng nào khác trong dự án của tôi và chỉ được gọi bởi các đại biểu. Có nói rằng tôi chỉ thử nghiệm phương pháp công cộng. Các đại biểu này được tiếp xúc công khai. Giới thiệu một lĩnh vực khác có thể là một cách để đi nhưng bạn đúng, nó sẽ bị bẩn. Tôi sẽ xem xét liên kết Thỏa thuận đại biểu được chờ đợi mà bạn đã gửi cho tôi và xem liệu nó có hữu ích hay không. –

+0

Cập nhật: Tôi đã triển khai câu trả lời ở trên của bạn cho thực tế là tôi chưa thể tập luyện giải pháp thay thế khác cho giải pháp - ví dụ: Delegate DelegateCommand. Thực hiện điều này có nghĩa là tôi đã thay đổi các phương thức riêng của mình thành public (Mùi này!), Bây giờ vấn đề của tôi là khi GetTaskAsync() được gọi bằng cách sử dụng t.Wait() này ném InnerException = {"Loại CollectionView này không hỗ trợ thay đổi SourceCollection từ một chủ đề khác với chủ đề Dispatcher. "}. Điều này bởi vì nó thêm các mục vào bộ sưu tập của tôi từ chủ đề khác. Bất kỳ ý tưởng? –

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