Quello che faccio in genere è creare un'interfaccia per un servizio applicativo che esegue questa funzione. Nei miei esempi presumo che tu stia utilizzando qualcosa come MVVM Toolkit o qualcosa di simile (quindi posso ottenere un ViewModel di base e un RelayCommand).
Ecco un esempio di un'interfaccia estremamente semplice per eseguire operazioni di I/O di base come OpenFileDialog e OpenFile. Li sto mostrando entrambi qui, quindi non pensi che ti stia suggerendo di creare un'interfaccia con un metodo per aggirare questo problema.
public interface IOService
{
string OpenFileDialog(string defaultPath);
//Other similar untestable IO operations
Stream OpenFile(string path);
}
Nell'applicazione, si fornisce un'implementazione predefinita di questo servizio. Ecco come lo consumeresti.
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;
}
}
}
Quindi è piuttosto semplice. Ora per l'ultima parte: testabilità. Questo dovrebbe essere ovvio, ma ti mostrerò come fare un semplice test per questo. Io uso Moq per lo stub, ma puoi usare quello che vuoi ovviamente.
[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);
}
Questo probabilmente funzionerà per voi.
C'è una biblioteca su CodePlex chiamato "SystemWrapper" (http://systemwrapper.codeplex.com) che si potrebbe evitare di dover fare un sacco di questo genere di cose. Sembra che FileDialog non sia ancora supportato, quindi dovrai sicuramente scrivere un'interfaccia per quello.
Spero che questo aiuti.
Edit:
Mi sembra di ricordare che si favorendo TypeMock Isolator per il vostro quadro falsificazione. Ecco lo stesso test utilizzando 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);
}
Spero che questo sia utile pure.
Questo è un duplicato di: http://stackoverflow.com/questions/1043918/ open-file-dialog-mvvm –
Sicuro. :-) Ho fatto alcune ricerche su SO prima di pubblicare questa domanda, non è venuto fuori. Oh bene. –
Ho votato per chiudere questa domanda, in quanto è un duplicato esatto. –