📜  MVVMÂ单元测试

📅  最后修改于: 2020-11-19 05:27:13             🧑  作者: Mango


单元测试背后的想法是采用离散的代码块(单元)并编写以预期方式使用该代码的测试方法,然后进行测试以查看它们是否获得了预期的结果。

  • 作为代码本身,单元测试就像项目的其余部分一样进行编译。

  • 它们也由运行测试的软件执行,该软件可以加快每个测试的速度,有效地表示赞成或反对,分别表示测试已通过或失败。

让我们看一下前面创建的示例。以下是学生模型的实现。

using System.ComponentModel;

namespace MVVMDemo.Model {
 
   public class StudentModel {}
    
   public class Student : INotifyPropertyChanged { 
      private string firstName; 
      private string lastName;

      public string FirstName { 
         get { return firstName; }
            
         set { 
            if (firstName != value) { 
               firstName = value; 
               RaisePropertyChanged("FirstName");
               RaisePropertyChanged("FullName"); 
            } 
         }
      }

      public string LastName { 
         get { return lastName; } 
            
         set { 
            if (lastName != value) { 
               lastName = value; 
               RaisePropertyChanged("LastName");
               RaisePropertyChanged("FullName");
            } 
         } 
      }

      public string FullName { 
         get { 
            return firstName + " " + lastName; 
         } 
      }

      public event PropertyChangedEventHandler PropertyChanged;

      private void RaisePropertyChanged(string property) { 
         if (PropertyChanged != null) { 
            PropertyChanged(this, new PropertyChangedEventArgs(property)); 
         } 
      } 
   } 
}

以下是StudentView的实现。



    
       
        
          
             
                    
             
                    
             
          
            
       
   

    
       
          
                
          
       
   


以下是StudentViewModel实现。

using MVVMDemo.Model;
 
using System.Collections.ObjectModel; 
using System.Windows.Input; 
using System;

namespace MVVMDemo.ViewModel { 

   public class StudentViewModel { 
    
      public MyICommand DeleteCommand { get; set;}
        
      public StudentViewModel() { 
         LoadStudents(); 
         DeleteCommand = new MyICommand(OnDelete, CanDelete); 
      }

      public ObservableCollection Students { 
         get; 
         set; 
      }

      public void LoadStudents() { 
         ObservableCollection students = new ObservableCollection();

         students.Add(new Student { FirstName = "Mark", LastName = "Allain" }); 
         students.Add(new Student { FirstName = "Allen", LastName = "Brown" }); 
         students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
            
         Students = students; 
      } 
        
      private Student _selectedStudent; 
        
      public Student SelectedStudent { 
         get { 
            return _selectedStudent; 
         } 
            
         set { 
            _selectedStudent = value;
            DeleteCommand.RaiseCanExecuteChanged(); 
         } 
      } 
        
      private void OnDelete() { 
         Students.Remove(SelectedStudent); 
      }

      private bool CanDelete() { 
         return SelectedStudent != null; 
      }
        
      public int GetStudentCount() { 
         return Students.Count; 
      } 
   } 
}

以下是MainWindow.xaml文件。



    
       
   
 

以下是MyICommand实现,该实现实现了ICommand接口。

using System; 
using System.Windows.Input;

namespace MVVMDemo { 

   public class MyICommand : ICommand { 
      Action _TargetExecuteMethod; 
      Func _TargetCanExecuteMethod;

      public MyICommand(Action executeMethod) { 
         _TargetExecuteMethod = executeMethod; 
      }

      public MyICommand(Action executeMethod, Func canExecuteMethod) { 
         _TargetExecuteMethod = executeMethod;
         _TargetCanExecuteMethod = canExecuteMethod; 
      }

      public void RaiseCanExecuteChanged() {
         CanExecuteChanged(this, EventArgs.Empty); 
      }
        
      bool ICommand.CanExecute(object parameter) { 
        
         if (_TargetCanExecuteMethod != null) { 
            return _TargetCanExecuteMethod();
         } 
            
         if (_TargetExecuteMethod != null) { 
            return true; 
         } 
            
         return false; 
      }
        
      // Beware - should use weak references if command instance lifetime
         is longer than lifetime of UI objects that get hooked up to command
            
      // Prism commands solve this in their implementation
        
      public event EventHandler CanExecuteChanged = delegate { };

      void ICommand.Execute(object parameter) { 
         if (_TargetExecuteMethod != null) { 
            _TargetExecuteMethod(); 
         } 
      } 
   }
}

编译并执行上述代码后,您将在主窗口中看到以下输出。

MVVM单元测试MainWindow

要为上述示例编写单元测试,让我们向解决方案中添加一个新的测试项目。

添加新项目

通过右键单击“引用”将引用添加到项目。

添加新参考

选择现有项目,然后单击确定。

Reference Manager MVVM测试

现在让我们添加一个简单的测试,它将检查学生人数,如以下代码所示。

using System; 

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using MVVMDemo.ViewModel;

namespace MVVMTest { 
   [TestClass] 
    
   public class UnitTest1 { 
      [TestMethod] 
        
      public void TestMethod1() { 
         StudentViewModel sViewModel = new StudentViewModel(); 
         int count = sViewModel.GetStudentCount();
         Assert.IsTrue(count == 3); 
      } 
   } 
}

要执行此测试,请选择“测试”→“运行”→“所有测试”菜单选项。

执行MVVM测试

您可以在“测试资源管理器”中看到测试已通过,因为在StudentViewModel中添加了三个学生。如以下代码所示,将计数条件从3更改为4。

using System; 

using Microsoft.VisualStudio.TestTools.UnitTesting; 
using MVVMDemo.ViewModel;

namespace MVVMTest { 
   [TestClass] 
    
   public class UnitTest1 { 
      [TestMethod] public void TestMethod1() {
         StudentViewModel sViewModel = new StudentViewModel(); 
         int count = sViewModel.GetStudentCount();
         Assert.IsTrue(count == 4);
      } 
   } 
}

再次执行测试计划时,您会看到测试失败,因为学生人数不等于4。

MVVM测试失败

我们建议您以逐步的方法执行上面的示例,以更好地理解。