Home > Archive > Extreme Programming > May 2005 > Unit Testing FileSystemWatcher (Part 2)
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Unit Testing FileSystemWatcher (Part 2)
|
|
| Harris 2005-05-19, 3:57 pm |
| Hi all,
I'm having difficulty testing a component within the .NET Framework. A
while back (about a month probably) I posted on testing the
FileSystemWatcher component that ships with the Framework. To be
honest, I had given up and scraped the attempt and focused on getting
the core of the application tested and written.
Now, I'm back to where I was before. This time, I feel I'm on a
mission. Here's my scenario: The users of my application will
download a file and save it to a specified directory. When the file is
created, I need to handle that event and do processing on that file.
It appears as though Internet Explorer, when saving a download, causes
the FileSystemWatcher (FSW here out) to generate multiple Created
events. I manually tested an confirmed this by writing a console
application that watched a directory, downloading a file from my
system, saving it to the watched directory, and outputing a message
when the Created event was raised.
What I'd like to do is replicate this, except as an automated test.
I'd like to test that the FSW component is watching the specified
directory and handling the Created event. I'd then like to modify the
code that handles the event to ensure that each file is only processed
once. However, my tests fail as the FSW component doesn't not seem to
be capturing the Created event when executed from within NUnit
(v2.2.0). Changed events appear to be working fine, however.
My code is actually inspired by the tests written for NUnit, as the GUI
watches the appropriate director(ies) for changes to the test
assemeblies that are loaded. I am considering contacting the NUnit
team to see if this is a defect, but I wanted to get some other
opinions prior to doing so.
I'd appreciate any thoughts or ideas anyone might have.
Thanks,
Harris
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
Code (not yet refactored)
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
using System;
using System.IO;
using NUnit.Framework;
namespace TestedFileWatcher
{
/// <summary>
/// Summary description for FileWatcherFixture.
/// </summary>
[TestFixture]
public class FileWatcherFixture
{
private WatcherChangeTypes changeType = 0;
private string handledFile = null;
public FileWatcherFixture() {}
[TearDown]
public void ResetFixture()
{
changeType = 0;
handledFile = null;
}
[Test]
public void Hookup()
{
Assert.IsTrue(true);
}
[Test]
public void CaptureFileCreated()
{
string fileCreated = Path.GetTempFileName();
Assert.IsTrue(fileCreated.EndsWith(".tmp"), "not a temp file");
FileSystemWatcher watcher = new
FileSystemWatcher(Path.GetTempPath(), new FileInfo(fileCreated).Name);
watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite;
Console.Out.WriteLine("Watched path: {0}", watcher.Path);
Console.Out.WriteLine("Watched filter: {0}", watcher.Filter);
Console.Out.WriteLine("Watched Notifications: {0}",
watcher.NotifyFilter);
watcher.Created += new FileSystemEventHandler(watcher_Created);
watcher.Changed += new FileSystemEventHandler(w_Changed);
watcher.EnableRaisingEvents = true;
using(TextWriter tw = new StreamWriter(fileCreated))
{
tw.WriteLine("Data");
tw.Flush();
tw.Close();
System.Threading.Thread.Sleep(250);
}
Assert.IsTrue(File.Exists(fileCreated));
Assert.AreEqual(fileCreated.ToLower(), handledFile.ToLower(), "File
handled != file created");
Assert.AreEqual(WatcherChangeTypes.Created, changeType, "Captured
non-created event");
File.Delete(fileCreated);
Assert.IsFalse(File.Exists(fileCreated), "File Exists after
deletion");
watcher.Dispose();
watcher = null;
}
[Test]
public void CaputreFileChanged()
{
string file = Path.GetTempFileName();
using(TextWriter tw = File.CreateText(file))
{
tw.WriteLine("Data");
tw.Flush();
tw.Close();
}
Assert.IsTrue(File.Exists(file));
FileSystemWatcher w = new FileSystemWatcher(Path.GetTempPath(), new
FileInfo(file).Name);
Console.Out.WriteLine("Watched path: {0}", w.Path);
Console.Out.WriteLine("Watched filter: {0}", w.Filter);
w.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite;
w.Changed += new FileSystemEventHandler(w_Changed);
w.EnableRaisingEvents = true;
using(TextWriter tw = File.AppendText(file))
{
tw.WriteLine("Data 2");
tw.Flush();
tw.Close();
}
System.Threading.Thread.Sleep(250);
Assert.AreEqual(file.ToLower(), handledFile.ToLower(), "file handled
not my file");
Assert.AreEqual(WatcherChangeTypes.Changed, changeType, "Captured
non-change event");
w.EnableRaisingEvents = false;
File.Delete(file);
Assert.IsFalse(File.Exists(file), "file exists after deletion");
}
private void watcher_Created(object sender, FileSystemEventArgs e)
{
changeType = e.ChangeType;
}
private void w_Changed(object sender, FileSystemEventArgs e)
{
handledFile = e.FullPath;
changeType = e.ChangeType;
}
}
}
| |
| Harris 2005-05-19, 3:57 pm |
| OK, that was embarassing...After a few necessary modifications - due to
not testing before posting - here's the revised code
Thanks again,
Harris
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
Code
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
using System;
using System.IO;
using NUnit.Framework;
namespace TestedFileWatcher
{
/// <summary>
/// Summary description for FileWatcherFixture.
/// </summary>
[TestFixture]
public class FileWatcherFixture
{
private WatcherChangeTypes changeType = 0;
private string handledFile = "";
public FileWatcherFixture() {}
[TearDown]
public void ResetFixture()
{
changeType = 0;
handledFile = "";
}
[Test]
public void Hookup()
{
Assert.IsTrue(true);
}
[Test]
public void CaptureFileCreated()
{
string fileCreated = Path.GetTempFileName();
Assert.IsTrue(fileCreated.EndsWith(".tmp"), "not a temp file");
FileSystemWatcher watcher = new
FileSystemWatcher(Path.GetTempPath(), new FileInfo(fileCreated).Name);
watcher.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite;
Console.Out.WriteLine("Watched path: {0}", watcher.Path);
Console.Out.WriteLine("Watched filter: {0}", watcher.Filter);
Console.Out.WriteLine("Watched Notifications: {0}",
watcher.NotifyFilter);
watcher.Created += new FileSystemEventHandler(watcher_Created);
// watcher.Changed += new FileSystemEventHandler(w_Changed);
watcher.EnableRaisingEvents = true;
using(TextWriter tw = new StreamWriter(fileCreated))
{
tw.WriteLine("Data");
tw.Flush();
tw.Close();
System.Threading.Thread.Sleep(250);
}
Assert.IsTrue(File.Exists(fileCreated));
Assert.AreEqual(fileCreated.ToLower(), handledFile.ToLower(), "File
handled != file created");
Assert.AreEqual(WatcherChangeTypes.Created, changeType, "Captured
non-created event");
File.Delete(fileCreated);
Assert.IsFalse(File.Exists(fileCreated), "File Exists after
deletion");
watcher.Dispose();
watcher = null;
}
[Test]
public void CaputreFileChanged()
{
string file = Path.GetTempFileName();
using(TextWriter tw = File.CreateText(file))
{
tw.WriteLine("Data");
tw.Flush();
tw.Close();
}
Assert.IsTrue(File.Exists(file));
FileSystemWatcher w = new FileSystemWatcher(Path.GetTempPath(), new
FileInfo(file).Name);
Console.Out.WriteLine("Watched path: {0}", w.Path);
Console.Out.WriteLine("Watched filter: {0}", w.Filter);
w.NotifyFilter = NotifyFilters.Size | NotifyFilters.LastWrite;
w.Changed += new FileSystemEventHandler(w_Changed);
w.EnableRaisingEvents = true;
using(TextWriter tw = File.AppendText(file))
{
tw.WriteLine("Data 2");
tw.Flush();
tw.Close();
}
System.Threading.Thread.Sleep(250);
Assert.AreEqual(file.ToLower(), handledFile.ToLower(), "file handled
not my file");
Assert.AreEqual(WatcherChangeTypes.Changed, changeType, "Captured
non-change event");
w.EnableRaisingEvents = false;
File.Delete(file);
Assert.IsFalse(File.Exists(file), "file exists after deletion");
}
private void watcher_Created(object sender, FileSystemEventArgs e)
{
changeType = e.ChangeType;
handledFile = e.FullPath;
}
private void w_Changed(object sender, FileSystemEventArgs e)
{
handledFile = e.FullPath;
changeType = e.ChangeType;
}
}
}
| |
| Robert C. Martin 2005-05-26, 3:56 am |
| On 19 May 2005 09:04:30 -0700, "Harris" <harris.r.boyce.iii@gmail.com>
wrote:
>Hi all,
>
>I'm having difficulty testing a component within the .NET Framework. A
>while back (about a month probably) I posted on testing the
>FileSystemWatcher component that ships with the Framework. To be
>honest, I had given up and scraped the attempt and focused on getting
>the core of the application tested and written.
>
>Now, I'm back to where I was before. This time, I feel I'm on a
>mission. Here's my scenario: The users of my application will
>download a file and save it to a specified directory. When the file is
>created, I need to handle that event and do processing on that file.
>It appears as though Internet Explorer, when saving a download, causes
>the FileSystemWatcher (FSW here out) to generate multiple Created
>events. I manually tested an confirmed this by writing a console
>application that watched a directory, downloading a file from my
>system, saving it to the watched directory, and outputing a message
>when the Created event was raised.
>
>What I'd like to do is replicate this, except as an automated test.
>I'd like to test that the FSW component is watching the specified
>directory and handling the Created event. I'd then like to modify the
>code that handles the event to ensure that each file is only processed
>once. However, my tests fail as the FSW component doesn't not seem to
>be capturing the Created event when executed from within NUnit
>(v2.2.0). Changed events appear to be working fine, however.
>
>My code is actually inspired by the tests written for NUnit, as the GUI
>watches the appropriate director(ies) for changes to the test
>assemeblies that are loaded. I am considering contacting the NUnit
>team to see if this is a defect, but I wanted to get some other
>opinions prior to doing so.
>
>I'd appreciate any thoughts or ideas anyone might have.
You might want to create a completely new executable that simply
creates a file. Then have your NUnit test invoke that new executable
from the command line. (There's got to be a system call that allows
you to do this).
-----
Robert C. Martin (Uncle Bob) | email: unclebob@objectmentor.com
Object Mentor Inc. | blog: www.butunclebob.com
The Agile Transition Experts | web: www.objectmentor.com
800-338-6716
"The aim of science is not to open the door to infinite wisdom,
but to set a limit to infinite error."
-- Bertolt Brecht, Life of Galileo
|
|
|
|
|