TDD Test Refactoring to support MultiThreading TDD Test Refactoring to support MultiThreading multithreading multithreading

TDD Test Refactoring to support MultiThreading


I've run into similar problems with ASP.NET MVC where it is the HttpContext that is missing. One thing you can do is provide an alternate constructor that allows you to inject a mock SynchronizationContext or expose a public setter that does the same thing. If you can't change the SynchronizationContext internally, then make a property that you set to the SynchronizationContext.Current in the default constructor and use that property throughout your code. In your alternate constructor, you can assign the mock context to the property -- or you can assign to it directly if you give it a public setter.

public class FtpPresenter : IFtpPresenter { public SynchronizationContext CurrentContext { get; set; }

   public FtpPresenter() : this(null) { }   public FtpPresenter( SynchronizationContext context )   {       this.CurrentContext = context ?? SynchronizationContext.Current;   }   void _view_GetFilesClicked(object sender, EventArgs e)   {     ....     new Thread(new ThreadStart(delegate        {            var files = _ftpService.GetFiles(settings);            this.CurrentContext.Send(delegate            {                _view.FilesDataSource = files;                _view.StatusMessage = Messages.Done;            }, null);        })).Start();    ...   }

One other observation that I would make is that I would probably have your presenter depend on an interface to the Thread class rather than on Thread directly. I don't think that your unit tests should be creating new threads but rather interacting with a mock class that just ensures that the proper methods to create threads get called. You could inject that dependency as well.

If the SynchronizationContext.Current doesn't exist when the constructor is called, you may need to move the assignment logic to Current into the getter and do lazy load.


You have to much app-logic in your presenter. I would hide contexts and threads inside a concrete model and test the functionality alone.