
- MVVM 教程
- MVVM - 首頁
- MVVM – 簡介
- MVVM - 優點
- MVVM - 職責
- MVVM - 第一個應用程式
- MVVM - 連線檢視
- MVVM - 連線 ViewModel
- MVVM - WPF 資料繫結
- MVVM - WPF 資料模板
- MVVM - ViewModel 通訊
- MVVM - 層次結構和導航
- MVVM - 驗證
- MVVM - 依賴注入
- MVVM - 事件
- MVVM - 單元測試
- MVVM - 框架
- MVVM - 面試問題
- MVVM 有用資源
- MVVM - 快速指南
- MVVM - 有用資源
- MVVM - 討論
MVVM – 單元測試
單元測試的理念是將程式碼的離散塊(單元)提取出來,編寫測試方法以預期的方式使用這些程式碼,然後測試它們是否獲得預期結果。
單元測試本身也是程式碼,與專案的其餘部分一樣進行編譯。
它們也由測試執行軟體執行,該軟體可以快速完成每個測試,有效地給出贊成或反對的意見,以分別指示測試是否透過或失敗。
讓我們看一下之前建立的一個示例。以下是學生模型的實現。
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 的實現。
<UserControl x:Class="MVVMDemo.Views.StudentView" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:local = "clr-namespace:MVVMDemo.Views" xmlns:viewModel = "clr-namespace:MVVMDemo.ViewModel" xmlns:data = "clr-namespace:MVVMDemo.Model" xmlns:vml = "clr-namespace:MVVMDemo.VML" vml:ViewModelLocator.AutoHookedUpViewModel = "True" mc:Ignorable = "d" d:DesignHeight = "300" d:DesignWidth = "300"> <UserControl.Resources> <DataTemplate DataType = "{x:Type data:Student}"> <StackPanel Orientation = "Horizontal"> <TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}" Width = "100" Margin = "3 5 3 5"/> <TextBox Text = "{Binding Path = LastName, Mode = TwoWay}" Width = "100" Margin = "0 5 3 5"/> <TextBlock Text = "{Binding Path = FullName, Mode = OneWay}" Margin = "0 5 3 5"/> </StackPanel> </DataTemplate> </UserControl.Resources> <Grid> <StackPanel Orientation = "Horizontal"> <ListBox ItemsSource = "{Binding Students}" SelectedItem = "{Binding SelectedStudent}"/> <Button Content = "Delete" Command = "{Binding DeleteCommand}" HorizontalAlignment = "Left" VerticalAlignment = "Top" Width = "75" /> </StackPanel> </Grid> </UserControl>
以下是 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<Student> Students { get; set; } public void LoadStudents() { ObservableCollection<Student> students = new ObservableCollection<Student>(); 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 檔案。
<Window x:Class = "MVVMDemo.MainWindow" xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d = "http://schemas.microsoft.com/expression/blend/2008" xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local = "clr-namespace:MVVMDemo" xmlns:views = "clr-namespace:MVVMDemo.Views" mc:Ignorable = "d" Title = "MainWindow" Height = "350" Width = "525"> <Grid> <views:StudentView x:Name = "StudentViewControl"/> </Grid> </Window>
以下是 MyICommand 的實現,它實現了 ICommand 介面。
using System; using System.Windows.Input; namespace MVVMDemo { public class MyICommand : ICommand { Action _TargetExecuteMethod; Func<bool> _TargetCanExecuteMethod; public MyICommand(Action executeMethod) { _TargetExecuteMethod = executeMethod; } public MyICommand(Action executeMethod, Func<bool> 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(); } } } }
編譯並執行上述程式碼後,您將在主視窗上看到以下輸出。

要為上述示例編寫單元測試,讓我們向解決方案新增一個新的測試專案。

透過右鍵單擊“引用”新增對專案的引用。

選擇現有專案並單擊“確定”。

現在讓我們新增一個簡單的測試,它將檢查如下程式碼所示的學生數量。
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); } } }
要執行此測試,請選擇“測試”→“執行”→“所有測試”選單選項。

您可以在測試資源管理器中看到測試已透過,因為在 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。

我們建議您以分步方法執行上述示例,以更好地理解。
廣告