2016-05-19 4 views
0

私はMvvm LightとNinjectを使用するXFプロジェクトを持っています。 私はビューモデルのユニットテストをバックトラックして記述しようとしていますが、Xamarin.Forms.Init()を呼び出す必要がある問題や、RelayCommandsのDevice.BeginInvokeOnMainThreadや他のUI固有のものへの参照があります。ユニットテストのためにXamarin Forms viewmodelでコードを整理するには?

ので、典型的なRelayCommandは次のようになります。

public RelayCommand DeleteGameCommand 
{ 
    get 
    { 
     return _deleteGameCommand 
      ?? (_deleteGameCommand = new RelayCommand(
      async() => 
      { 
       Device.BeginInvokeOnMainThread(() => ToggleMasterMenuDisplayCommand.Execute(null)); 
       var response = await 
        ((MasterDetailPage) Application.Current.MainPage).Detail.DisplayActionSheet("Are you sure?", "Cancel", 
         "Delete Game"); 
       if (response == "Delete Game") 
       { 
        StopTimer(); 

        using (new Busy(this, "Deleting Game...")) 
        { 
         await GameService.DeleteGame(Game, true); 
         await AzureService.SyncGameInfoForGame(Game.GameId, true); 
        } 

        App.Current.Container.Get<DashboardViewModel>().ShouldRefreshDataOnNextDisplay(); 
        Device.BeginInvokeOnMainThread(() => 
        { 
         App.Current.HideLoading(); 
         LoadHomeAsMainPage(); 
        }); 
       } 
      })); 
    } 
} 

ビジーは()進捗インジケーターを表示するには、いくつかのUIのものを呼び出します。 App.Current.Containerは私のNinjectカーネルです。

は、私はより多くのようなものにこれをリファクタリングする探している必要があります:

public RelayCommand DeleteGameCommand 
{ 
    get 
    { 
     return _deleteGameCommand 
      ?? (_deleteGameCommand = new RelayCommand(
      async() => 
      { 
       Device.BeginInvokeOnMainThread(() => ToggleMasterMenuDisplayCommand.Execute(null)); 
       var response = await 
        ((MasterDetailPage) Application.Current.MainPage).Detail.DisplayActionSheet("Are you sure?", "Cancel", 
         "Delete Game"); 
       if (response == "Delete Game") 
       { 
        StopTimer(); 

        using (new Busy(this, "Deleting Game...")) 
        { 
         await BusinessLogic.DeleteGame(Game,true); 
        } 

        App.Current.Container.Get<DashboardViewModel>().ShouldRefreshDataOnNextDisplay(); 
        Device.BeginInvokeOnMainThread(() => 
        { 
         App.Current.HideLoading(); 
         LoadHomeAsMainPage(); 
        }); 
       } 
      })); 
    } 
} 



public class BusinessLogic 
{ 
    public async Task DeleteGame(Game game, bool includeRelated) 
    { 
     await GameService.DeleteGame(game, true); 
     await AzureService.SyncGameInfoForGame(game.GameId, true); 
    } 
} 

私は2つのサービスコールがすでにユニットテストが、他の中継である可能性が高いので、これは最良の例ではないかもしれません実現しますサービスへの呼び出しだけではありません。

私はこのようなことをすれば、すべてのビジネスロジックをテストし、RelayCommandを呼び出すテストを書くことはできないと私は考えていました。

単体テストのビューモデルにどのように近づいているのかよく分かりませんが、私が見つけた情報の多くは非常にシンプルな例があります。

答えて

0

一般に、テストを自動化すると、代わりにこれらのスタブが実行されるように、ラッパーを作成して呼び出します。モックされたInitとBeginInvokeOnMainThreadは異なる実装に転送されるかもしれません。

+0

ありがとうございました。ええ、なぜ私はサービスですべての静的呼び出しをラップしてから、自分が望むものを返すか、テスト実装を提供するためにそれらを嘲笑することはできません。私は自分の頭が他のプロジェクトタイプで普通にやっていることを考えるために "モバイル"で包まれすぎていたと思います。それは私がTDDしなかったのと同じ理由で、ちょうどコードを書くようになった。 – jmichas

関連する問題