Vì vậy, tôi là người mới dùng TDD và tôi đã tạo thành công một ứng dụng mẫu nhỏ đẹp bằng mẫu MVP. Vấn đề lớn đối với giải pháp hiện tại của tôi là nó chặn luồng UI, Vì vậy, tôi đã cố gắng để thiết lập Presenter để sử dụng SynchronizationContext.Current, nhưng khi tôi chạy thử nghiệm của tôi SynchronizationContext.Current là null.Tái cấu trúc thử nghiệm TDD để hỗ trợ đa luồng
Presenter Trước Threading
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;
}
}
...
}
Kiểm tra Trước khi Threading
[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);
}
Bây giờ sau khi tôi thêm một SynchronizationContext Threading cho Presenter tôi đã cố gắng để thiết lập một AutoResetEvent trên Xem Fake tôi cho StatusMessage, nhưng khi Tôi chạy thử nghiệm SynchronizationContext.Current là null. Tôi nhận ra rằng các mô hình luồng tôi đang sử dụng trong thuyết trình mới của tôi không phải là hoàn hảo, nhưng đây có phải là kỹ thuật đúng cho kiểm tra đa luồng? Tại sao là SynchronizationContext.Current null của tôi? Tôi nên làm gì?
Presenter Sau Threading
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;
}
}
...
}
thử nghiệm sau khi luồng
[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);
}
Fake Xem
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();
}
}
...
}
Câu hỏi hay! Tôi đang cố giải quyết vấn đề tương tự! –