私が通常行うことは、この機能を実行するアプリケーション サービスのインターフェイスを作成することです。私の例では、MVVM Toolkit などを使用していると仮定します (したがって、基本 ViewModel と を取得できますRelayCommand
)。
OpenFileDialog
や などの基本的な IO 操作を行うための非常に単純なインターフェイスの例を次に示しますOpenFile
。ここでは両方を示しているので、この問題を回避するために 1 つのメソッドで 1 つのインターフェイスを作成することを提案しているとは思わないでください。
public interface IOService
{
string OpenFileDialog(string defaultPath);
//Other similar untestable IO operations
Stream OpenFile(string path);
}
アプリケーションでは、このサービスのデフォルトの実装を提供します。これがあなたがそれを消費する方法です。
public MyViewModel : ViewModel
{
private string _selectedPath;
public string SelectedPath
{
get { return _selectedPath; }
set { _selectedPath = value; OnPropertyChanged("SelectedPath"); }
}
private RelayCommand _openCommand;
public RelayCommand OpenCommand
{
//You know the drill.
...
}
private IOService _ioService;
public MyViewModel(IOService ioService)
{
_ioService = ioService;
OpenCommand = new RelayCommand(OpenFile);
}
private void OpenFile()
{
SelectedPath = _ioService.OpenFileDialog(@"c:\Where\My\File\Usually\Is.txt");
if(SelectedPath == null)
{
SelectedPath = string.Empty;
}
}
}
とても簡単です。最後の部分:テスト容易性。これは明らかなはずですが、これを簡単にテストする方法を紹介します。私はスタブに Moq を使用していますが、もちろん好きなものを使用できます。
[Test]
public void OpenFileCommand_UserSelectsInvalidPath_SelectedPathSetToEmpty()
{
Mock<IOService> ioServiceStub = new Mock<IOService>();
//We use null to indicate invalid path in our implementation
ioServiceStub.Setup(ioServ => ioServ.OpenFileDialog(It.IsAny<string>()))
.Returns(null);
//Setup target and test
MyViewModel target = new MyViewModel(ioServiceStub.Object);
target.OpenCommand.Execute();
Assert.IsEqual(string.Empty, target.SelectedPath);
}
これはおそらくあなたのために働くでしょう。
CodePlex には「SystemWrapper」( http://systemwrapper.codeplex.com ) と呼ばれるライブラリがあり、この種の多くの作業を省くことができます。FileDialog
はまだサポートされていないようなので、そのためのインターフェイスを必ず作成する必要があります。
お役に立てれば。
編集:
偽のフレームワークに TypeMock Isolator を好んでいたことを覚えているようです。Isolator を使用した同じテストを次に示します。
[Test]
[Isolated]
public void OpenFileCommand_UserSelectsInvalidPath_SelectedPathSetToEmpty()
{
IOService ioServiceStub = Isolate.Fake.Instance<IOService>();
//Setup stub arrangements
Isolate.WhenCalled(() => ioServiceStub.OpenFileDialog("blah"))
.WasCalledWithAnyArguments()
.WillReturn(null);
//Setup target and test
MyViewModel target = new MyViewModel(ioServiceStub);
target.OpenCommand.Execute();
Assert.IsEqual(string.Empty, target.SelectedPath);
}
これも役立つことを願っています。