Lo que generalmente hago es crear una interfaz para un servicio de aplicación que realiza esta función. En mis ejemplos, supongo que está utilizando algo como MVVM Toolkit o algo similar (para que pueda obtener un ViewModel base y un RelayCommand).
Aquí hay un ejemplo de una interfaz extremadamente simple para realizar operaciones básicas de IO como OpenFileDialog y OpenFile. Los mostraré aquí, así que no creo que sugiera que cree una interfaz con un método para evitar este problema.
public interface IOService
{
string OpenFileDialog(string defaultPath);
//Other similar untestable IO operations
Stream OpenFile(string path);
}
En su aplicación, debe proporcionar una implementación predeterminada de este servicio. Aquí es cómo lo consumirías.
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;
}
}
}
Así que eso es bastante simple. Ahora para la última parte: comprobabilidad. Este debería ser obvio, pero te mostraré cómo hacer una prueba simple para esto. Yo uso Moq para anotación, pero puedes usar lo que quieras, por supuesto.
[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);
}
Esto probablemente funcione para usted.
Hay una biblioteca a cabo en CodePlex llamado "SystemWrapper" (http://systemwrapper.codeplex.com) que pueden salvar de tener que hacer un montón de este tipo de cosas. Parece que FileDialog aún no es compatible, por lo que definitivamente tendrá que escribir una interfaz para ese.
Espero que esto ayude.
Editar:
creo recordar que favorece Typemock aislador para su marco falsificación. Aquí está la misma prueba utilizando aislador:
[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);
}
la esperanza que esto es útil también.
Este es un duplicado de: http://stackoverflow.com/questions/1043918/ open-file-dialog-mvvm –
Claro que sí. :-) Hice algunas búsquedas en SO antes de publicar esta pregunta, no apareció. Oh bien. –
He votado para cerrar esta pregunta, ya que es un duplicado exacto. –