I have a FileSystemWatcher
watching a directory for changes, and when there's a new XML file in it, it parses that file and does something with it.
I have a few sample XML files in my project that I am using for unit-testing purposes for the parser I wrote.
I'm looking for a way to use the sample XML files also to test the FileSystemWatcher
.
Is it possible to programatically create an event (somehow involving the XML file) in order to trigger the FSW.Changed
event?
The FileSystemWatcher provides us with the event handlers to capture events like renamed, deleted, created and changed.
The FileSystemWatcher class in the System.IO namespace can be used to monitor changes to the file system. It watches a file or a directory in your system for changes and triggers events when changes occur. In order for the FileSystemWatcher to work, you should specify a directory that needs to be monitored.
Nope, filesystemwatchers run on their own thread.
To watch for changes in all files, set the Filter property to an empty string ("") or use wildcards ("*. *"). To watch a specific file, set the Filter property to the file name. For example, to watch for changes in the file MyDoc.
I think that you are taking the wrong approach here.
You should not try to directly unit test the FileSystemWatcher
class (you can't - you have no control on it!). Instead, you can try the following:
1) Write a wrapper class for the FileSystemWatcher
class that only delegates its functionality to an instance of FileSystemWatcher
. Here's an example with one method and one event, add more members as required:
public class FileSystemWatcherWrapper
{
private readonly FileSystemWatcher watcher;
public event FileSystemEventHandler Changed;
public FileSystemWatcherWrapper(FileSystemWatcher watcher)
{
this.watcher = watcher
watcher.Changed += this.Changed;
}
public bool EnableRaisingEvents
{
get { return watcher.EnableRaisingEvents; }
set { watcher.EnableRaisingEvents = value; }
}
}
(Note how the instance of FileSystemWatcher
is passed to the class constructor; you could create a new instance on the fly instead when the wrapper is constructed)
2) Extract an interface for the class:
public interface IFileSystemWatcherWrapper
{
event FileSystemEventHandler Changed;
bool EnableRaisingEvents { get; set; }
}
//and therefore...
public class FileSystemWatcherWrapper : IFileSystemWatcherWrapper
3) Make your class dependant on the interface:
public class TheClassThatActsOnFilesystemChanges
{
private readonly IFileSystemWatcherWrapper fileSystemWatcher;
public TheClassThatActsOnFilesystemChanges(IFileSystemWatcherWrapper fileSystemWatcher)
{
this.fileSystemWatcher = fileSystemWatcher;
fileSystemWatcher.Changed += (sender, args) =>
{
//Do something...
};
}
}
4) At application initialization time, instantiate your class using any dependency injection engine, or just do poor man's injection:
var theClass = new TheClassThatActsOnFilesystemChanges(
new FileSystemWatcherWrapper(new FileSystemWatcher()));
5) Now go ahead and write unit tests for TheClassThatActsOnFilesystemChanges
by creating a mock of IFileSystemWatcherWrapper
that fires events at your will! You can use any mocking engine for that, for example Moq.
The bottom line:
When you have a dependency on a class that you don't control and/or can't be meaningfully unit tested, write a wrap around it with a proper interface, and depend on the interface. Your wrapper is so thin that it doesn't really hurt if you can't unit test it, while your client classes can now be properly unit tested.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With