2012-07-13 112 views
1

我剛看完Jason Dolinger's video on MVVM,我想澄清一下如何正確設置和單元測試我的視圖模型的ICommand屬性。我應該單元測試視圖模型上的方法還是命令?

考慮以下具有FooBarCommand ICommandProperty的ViewModel類。

public class ViewModel : IViewModel 
{ 
    public ICommand FooBarCommand { get; private set; } 

    public bool CanExectuteFooBar() 
    { 
     return true; 
    } 

    public void FooBar() 
    { 
     //Do some FooBarish stuff 
    } 
} 

public interface IViewModel 
{ 
    void FooBar(); 
    System.Windows.Input.ICommand FooBarCommand { get; } 
} 

public class FooBarCommand : ICommand 
{ 
    private ViewModel vm; 

    public FooBarCommand(ViewModel vm) 
    { 
     this.vm = vm; 
    } 
    public bool CanExecute(object parameter) 
    { 
     return vm.CanExectuteFooBar(); 
    } 

    public event EventHandler CanExecuteChanged; 

    public void Execute(object parameter) 
    { 
     vm.FooBar(); 
    } 
} 

所以,如果我的單元測試視圖模型()的FooBar的功能,我可以運行FooBar的通過調用testVM.FooBar()或通過調用testVM.FooBarCommand.Execute執行命令()。哪一個是首選?我傾向於測試FooBarCommand屬性,因爲最終視圖上的按鈕被綁定到FooBarCommand屬性而不是FooBar()方法。

此外,由於我的視圖將綁定到一個IViewModel而不是ViewModel,我應該能夠從IViewModel接口中省略FooBar()方法完全正確嗎?

+0

,如果你想你的單元測試視圖模型,你應該有一個IMessageboxService取代System.Windows.MessageBox.Show否則你就有麻煩了;) – blindmeis 2012-07-13 07:07:48

+0

哦,是的,我知道我沒有想到的是,當我做了例子。我現在解決了這個問題。 – 2012-07-13 19:34:26

+0

關於從界面中消除FooBar方法是正確的。該方法和CanExecute方法實際上可以是內部的。如果您開始測試方法與命令,那麼與測試類的私有實現與公共「接口」沒有什麼不同,因爲視圖模型的使用者只能使用該命令。 – Rich 2012-07-13 19:50:59

回答

0

爲什麼不使用DelegateCommand或RelayCommand?如果你這樣做,你不會問這個問題,因爲只有Comand本身是公開的 - 然後canexecute和execute方法是私有的。

我們只需要對公共資料進行單元測試。

ps:不要錯過我對你的問題的評論,直接在你的viewmodels中使用IMessageBoxService而不是MessageBox。

0

在某些情況下,測試命令可能是另一個測試夾具,因爲命令後面有邏輯(啓用禁用按鈕)。如果你只在CanExecute方法上返回true,那麼單元測試命令沒有用處,但是當你的disable-enable按鈕包含一個複雜的邏輯時,那麼你應該在不同的fixture中測試它。

說明(忽略它,如果不同意):

  1. 嘗試使用relay command要麼比通過VM進入 命令,儘量減少循環引用始終是最好的做法。
  2. 從未參考將不可測試對象整合到虛擬機(視圖 - 包括消息框,包含複雜依賴樹的大型對象等)中。
相關問題