Así que soy un novato en TDD, y creé con éxito una pequeña y bonita aplicación de muestra utilizando el patrón MVP. El problema principal de mi solución actual es que bloquea el hilo de la interfaz de usuario, así que estaba intentando configurar el presentador para usar SynchronizationContext.Current, pero cuando ejecuto mis pruebas, SynchronizationContext.Current es nulo.TDD Refactorización de prueba para admitir MultiThreading
Presentador antes de enhebrar
public class FtpPresenter : IFtpPresenter
{
...
void _view_GetFilesClicked(object sender, EventArgs e)
{
_view.StatusMessage = Messages.Loading;
try
{
var settings = new FtpAuthenticationSettings()
{
Site = _view.FtpSite,
Username = _view.FtpUsername,
Password = _view.FtpPassword
};
var files = _ftpService.GetFiles(settings);
_view.FilesDataSource = files;
_view.StatusMessage = Messages.Done;
}
catch (Exception ex)
{
_view.StatusMessage = ex.Message;
}
}
...
}
de prueba antes de enhebrar
[TestMethod]
public void Can_Get_Files()
{
var view = new FakeFtpView();
var presenter = new FtpPresenter(view, new FakeFtpService(), new FakeFileValidator());
view.GetFiles();
Assert.AreEqual(Messages.Done, view.StatusMessage);
}
Ahora, después he añadido un SynchronizationContext que rosca al presentador traté de establecer un AutoResetEvent en mi punto de vista falso para el StatusMessage, pero cuando Ejecuto la prueba SynchronizationContext.Current es nulo. Me doy cuenta de que el modelo de subprocesamiento que estoy usando en mi nuevo presentador no es perfecto, pero ¿es esta la técnica adecuada para probar el subprocesamiento múltiple? ¿Por qué mi SynchronizationContext.Current es nulo? ¿Qué debería hacer?
Presentador después de enhebrar
public class FtpPresenter : IFtpPresenter
{
...
void _view_GetFilesClicked(object sender, EventArgs e)
{
_view.StatusMessage = Messages.Loading;
try
{
var settings = new FtpAuthenticationSettings()
{
Site = _view.FtpSite,
Username = _view.FtpUsername,
Password = _view.FtpPassword
};
// Wrap the GetFiles in a ThreadStart
var syncContext = SynchronizationContext.Current;
new Thread(new ThreadStart(delegate
{
var files = _ftpService.GetFiles(settings);
syncContext.Send(delegate
{
_view.FilesDataSource = files;
_view.StatusMessage = Messages.Done;
}, null);
})).Start();
}
catch (Exception ex)
{
_view.StatusMessage = ex.Message;
}
}
...
}
prueba después de enhebrar
[TestMethod]
public void Can_Get_Files()
{
var view = new FakeFtpView();
var presenter = new FtpPresenter(view, new FakeFtpService(), new FakeFileValidator());
view.GetFiles();
view.GetFilesWait.WaitOne();
Assert.AreEqual(Messages.Done, view.StatusMessage);
}
Ver falso
public class FakeFtpView : IFtpView
{
...
public AutoResetEvent GetFilesWait = new AutoResetEvent(false);
public event EventHandler GetFilesClicked = delegate { };
public void GetFiles()
{
GetFilesClicked(this, EventArgs.Empty);
}
...
private List<string> _statusHistory = new List<string>();
public List<string> StatusMessageHistory
{
get { return _statusHistory; }
}
public string StatusMessage
{
get
{
return _statusHistory.LastOrDefault();
}
set
{
_statusHistory.Add(value);
if (value != Messages.Loading)
GetFilesWait.Set();
}
}
...
}
¡Buena pregunta! ¡Estoy tratando de resolver un problema similar! –