Ce que je fais généralement est de créer une interface pour une application de service qui exerce cette fonction. Dans mes exemples, je vais supposer que vous êtes en utilisant quelque chose comme le Toolkit MVVM ou chose semblable (si je peux obtenir une base ViewModel et un RelayCommand).
Voici un exemple d'une interface extrêmement simple pour faire des opérations d'e / s de base comme OpenFileDialog et OpenFile. Je suis les montrant tous les deux ici, tu ne pense pas que je suis en vous proposant de créer une interface avec une méthode pour contourner ce problème.
public interface IOService
{
string OpenFileDialog(string defaultPath);
//Other similar untestable IO operations
Stream OpenFile(string path);
}
Dans votre demande, vous devez fournir une implémentation par défaut de ce service. Voici comment vous pourriez consommer.
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;
}
}
}
Donc, c'est assez simple. Maintenant, pour la dernière partie: la testabilité. Celui-ci devrait être évident, mais je vais vous montrer comment faire un test simple pour cela. J'utilise Moq pour cogner, mais vous pouvez utiliser tout ce que vous souhaitez bien sûr.
[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);
}
Ce sera probablement pour vous.
Il y a une bibliothèque sur CodePlex appelé "SystemWrapper" (http://systemwrapper.codeplex.com) qui pourrait vous éviter d'avoir à faire beaucoup de ce genre de chose. Il ressemble à FileDialog n'est pas encore pris en charge, de sorte que vous aurez certainement à écrire une interface pour que l'on.
Espérons que cette aide.
Edit:
Il me semble me rappeler que vous favorisant TypeMock Isolateur pour votre semblant cadre. Voici le même test à l'aide de l'Isolateur:
[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);
}
Espérons que cela est utile.