我正在尝试创建一个类来监控Linux上的USB设备到达和删除。在Linux上,USB设备表示为/dev/bus/usb
下的设备文件,这些设备文件是为响应这些事件而创建/删除的。
跟踪这些事件似乎是使用FileSystemWatcher
的最佳方法。为了使类可测试,我正在使用System.IO.Abstractions
并在构造期间向类中注入IFileSystem
的实例。我想要的是创建一个行为类似于FileSystemWatcher
的东西,但监视注入IFileSystem
的更改,而不是直接监视真实文件系统。
从FileSystemWatcherBase
查看FileSystemWatcherWrapper
和System.IO.Abstractions
,我不知道该怎么做。目前我有这个(我知道这是错的):
public DevMonitor(
[NotNull] IFileSystem fileSystem,
[NotNull] IDeviceFileParser deviceFileParser,
[NotNull] ILogger logger,
[NotNull] string devDirectoryPath = DefaultDevDirectoryPath)
{
Raise.ArgumentNullException.IfIsNull(logger, nameof(logger));
Raise.ArgumentNullException.IfIsNull(devDirectoryPath, nameof(devDirectoryPath));
_fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem));
_deviceFileParser = deviceFileParser ?? throw new ArgumentNullException(nameof(deviceFileParser));
_logger = logger.ForContext<DevMonitor>();
_watcher = new FileSystemWatcherWrapper(devDirectoryPath);
}
答案 0 :(得分:2)
鉴于const express = require('express');
const mysql = require('mysql');
const app = express();
const connection = mysql.createConnection({
host: '127.0.0.1',
port: 5000,
user: 'root',
password: 'password'
});
connection.query('CREATE DATABASE IF NOT EXISTS test', function (err) {
if (err) throw err;
console.log("database created");
connection.query('USE test', function (err) {
if (err) throw err;
connection.query('CREATE TABLE IF NOT EXISTS users('
+ 'id INT NOT NULL AUTO_INCREMENT,'
+ 'PRIMARY KEY(id),'
+ 'name VARCHAR(30)'
+ ')', function (err) {
if (err) throw err;
});
});
});
// connection.end();
app.get('/', function (req, res) {
res.sendFile(__dirname + '/index.html');
console.log("send file index.html");
});
app.post('/users', function (req, res) {
connection.query('INSERT INTO users SET ?', req.body,
function (err, result) {
if (err) throw err;
res.send('User added to database with ID: ' + result.insertId);
}
);
});
const server = app.listen(5000, "127.0.0.1", function () {
const host = server.address().address;
const port = server.address().port;
console.log("app listening at http://%s:%s", host, port)
});
似乎还不支持这一点,我接受了这个:
我定义了System.IO.Abstractions
扩展IWatchableFileSystem
的接口:
IFileSystem
出于制作目的,我将其实现为/// <summary>
/// Represents a(n) <see cref="IFileSystem" /> that can be watched for changes.
/// </summary>
public interface IWatchableFileSystem : IFileSystem
{
/// <summary>
/// Creates a <c>FileSystemWatcher</c> that can be used to monitor changes to this file system.
/// </summary>
/// <returns>A <c>FileSystemWatcher</c>.</returns>
FileSystemWatcherBase CreateWatcher();
}
:
WatchableFileSystem
在我的单元测试类中,我将其实现为/// <inheritdoc />
public sealed class WatchableFileSystem : IWatchableFileSystem
{
private readonly IFileSystem _fileSystem;
/// <summary>
/// Initializes a new instance of the <see cref="WatchableFileSystem" /> class.
/// </summary>
public WatchableFileSystem() => _fileSystem = new FileSystem();
/// <inheritdoc />
public DirectoryBase Directory => _fileSystem.Directory;
/// <inheritdoc />
public IDirectoryInfoFactory DirectoryInfo => _fileSystem.DirectoryInfo;
/// <inheritdoc />
public IDriveInfoFactory DriveInfo => _fileSystem.DriveInfo;
/// <inheritdoc />
public FileBase File => _fileSystem.File;
/// <inheritdoc />
public IFileInfoFactory FileInfo => _fileSystem.FileInfo;
/// <inheritdoc />
public PathBase Path => _fileSystem.Path;
/// <inheritdoc />
public FileSystemWatcherBase CreateWatcher() => new FileSystemWatcher();
}
,它将MockWatchableFileSystem
和MockFileSystem
作为属性公开,我可以用它来安排&amp;在我的测试中断言:
Mock<FileSystemWatcherBase>
最后,在我的客户端类中,我可以这样做:
private class MockWatchableFileSystem : IWatchableFileSystem
{
/// <inheritdoc />
public MockWatchableFileSystem()
{
Watcher = new Mock<FileSystemWatcherBase>();
AsMock = new MockFileSystem();
AsMock.AddDirectory("/dev/bus/usb");
Watcher.SetupAllProperties();
}
public MockFileSystem AsMock { get; }
/// <inheritdoc />
public DirectoryBase Directory => AsMock.Directory;
/// <inheritdoc />
public IDirectoryInfoFactory DirectoryInfo => AsMock.DirectoryInfo;
/// <inheritdoc />
public IDriveInfoFactory DriveInfo => AsMock.DriveInfo;
/// <inheritdoc />
public FileBase File => AsMock.File;
/// <inheritdoc />
public IFileInfoFactory FileInfo => AsMock.FileInfo;
/// <inheritdoc />
public PathBase Path => AsMock.Path;
public Mock<FileSystemWatcherBase> Watcher { get; }
/// <inheritdoc />
public FileSystemWatcherBase CreateWatcher() => Watcher.Object;
}
在测试期间,客户端获取public DevMonitor(
[NotNull] IWatchableFileSystem fileSystem,
[NotNull] IDeviceFileParser deviceFileParser,
[NotNull] ILogger logger,
[NotNull] string devDirectoryPath = DefaultDevDirectoryPath)
{
// ...
_watcher = fileSystem.CreateWatcher();
_watcher.IncludeSubdirectories = true;
_watcher.EnableRaisingEvents = true;
_watcher.Path = devDirectoryPath;
}
包装IWatchableFileSystem
并返回MockFileSystem
的模拟实例。在制作过程中,它会FileSystemWatcherBase
包裹IWatchableFileSystem
并生成FileSystem
的唯一实例。