I have the following code that I'd like to test:
public class DirectoryProcessor
{
public string DirectoryPath
{
get;
set;
}
private FileSystemWatcher watcher;
public event EventHandler<SourceEventArgs> SourceFileChanged;
protected virtual void OnSourceFileChanged(SourceEventArgs e)
{
EventHandler<SourceEventArgs> handler = SourceFileChanged;
if(handler != null)
{
handler(this, e);
}
}
public DirectoryProcessor(string directoryPath)
{
this.DirectoryPath = directoryPath;
this.watcher = new FileSystemWatcher(directoryPath);
this.watcher.Created += new FileSystemEventHandler(Created);
}
void Created(object sender, FileSystemEventArgs e)
{
// process the newly created file
// then raise my own event indicating that processing is done
OnSourceFileChanged(new SourceEventArgs(e.Name));
}
}
Basically, I want to write an NUnit test that will do the following:
DirectoryProcessor
File.WriteAllText()
)DirectoryProcessor.SourceFileChanged
has fired once for each file added in step 3.I tried doing this and adding Thread.Sleep()
after step 3, but it's hard to get the timeout correct. It correctly processes the first file I write to the directory, but not the second (and that's with the timeout set to 60s). Even if I could get it working this way, it seems like a terrible way to write the test.
Does anyone have a good solution to this problem?
If you are looking to test another object that uses this class my answer is not relevant.
When I write unit tests to operations I prefer using the ManualResetEvent
The unit test will be something like:
...
DirectoryProcessor.SourceFileChanged+=onChanged;
manualResetEvent.Reset();
File.WriteAllText();
var actual = manualResetEvent.WaitOne(MaxTimeout);
...
when manualResetEvent is the ManualResetEvent and the MaxTimeout is some TimeSpan (my advice always use the time out). now we are missing the "onChanged":
private void onChanged(object sender, SourceEventArgs e)
{
manualResetEvent.Set();
}
I hope this is helpful