我有一个FileSystemWatcher监视目录中的更改,并且当其中有一个新的XML文件时,它将解析该文件并对其执行某些操作.
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.
我的项目中有一些示例XML文件,用于我编写的解析器的单元测试.
I have a few sample XML files in my project that I am using for unit-testing purposes for the parser I wrote.
我正在寻找一种使用示例XML文件来测试FileSystemWatcher的方法.
I'm looking for a way to use the sample XML files also to test the FileSystemWatcher.
是否可以通过编程方式创建事件(以某种方式涉及XML文件)以触发FSW.Changed事件?
推荐答案我认为您在这里采用了错误的方法.
I think that you are taking the wrong approach here.
您不应尝试直接对FileSystemWatcher类进行单元测试(您不能-无法控制它!).相反,您可以尝试以下操作:
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)为FileSystemWatcher类编写包装类,该包装类仅将委托给FileSystemWatcher实例.这是一个方法和一个事件的示例,根据需要添加更多成员:
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; } } }(请注意FileSystemWatcher的实例如何传递给类构造函数;构造包装器时,您可以动态创建一个新实例)
(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)提取类的接口:
public interface IFileSystemWatcherWrapper { event FileSystemEventHandler Changed; bool EnableRaisingEvents { get; set; } } //and therefore... public class FileSystemWatcherWrapper : IFileSystemWatcherWrapper3)使您的类依赖于接口:
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)在应用程序初始化时,使用任何依赖项注入引擎实例化您的类,或者只是进行穷人的注入:
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)现在,通过创建IFileSystemWatcherWrapper的模拟来编写TheClassThatActsOnFilesystemChanges的单元测试,该模拟可以随心所欲地触发事件!您可以为此使用任何模拟引擎,例如 Moq .
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.
底线:
当您对一个您无法控制的类和/或无法对其进行有意义的单元测试的依赖项时,请使用适当的接口对其进行包装,并依赖于该接口.包装器非常薄,以至于如果您不能对其进行单元测试,它实际上不会受到任何伤害,而现在您的客户端类可以进行正确的单元测试了.
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.
更多推荐
单元测试FileSystemWatcher:如何以编程方式触发更改的事件?
发布评论