我是第一次嘲笑和尝试moq的新手。我想知道我是否只能使用模拟编写测试?
public class FileCopierTests
{
private string path = AppDomain.CurrentDomain.BaseDirectory;
[Fact]
public void Copy_starts_copying_when_event_is_fired_returns_true()
{
var fullyQualifiedFileName = string.Format(@"{0}\..\..\Integration\TestData.xls", this.path);
var destFileName = Path.GetTempPath() + "66768c06-d1c4-4416-be81-767f36abeeb1.xls";
var copierMock = new Mock<IFileCopier>();
var watcherMock = new Mock<IFileWatcher>();
copierMock.Setup(cp => cp.Copy(fullyQualifiedFileName, destFileName)).Raises(
ev => ev.CopyingFinished += null, destFileName);
watcherMock.Object.Changed += arg => copierMock.Object.Copy(arg, destFileName);
watcherMock.Raise(e => e.Changed += null, fullyQualifiedFileName);
copierMock.VerifyAll();
}
}
这些是我想要测试的类和接口,
public interface IFileCopier
{
event Action<string> CopyingFinished;
void Copy(string fqFileName, string destFileName);
}
public class FileCopier : IFileCopier
{
private ReaderWriterLockSlim @lock = new ReaderWriterLockSlim();
public event Action<string> CopyingFinished;
public void Copy(string fqFileName, string destFileName)
{
this.@lock.EnterWriteLock();
try
{
File.Copy(fqFileName, destFileName, true);
if (this.CopyingFinished == null)
{
return;
}
this.CopyingFinished(destFileName);
}
finally
{
this.@lock.ExitWriteLock();
}
}
}
public interface IFileWatcher
{
event Action<string> Changed;
}
public class FileChangeWatcher : IFileWatcher
{
public FileChangeWatcher(FileSystemWatcher eyes)
{
this.Eyes = eyes;
this.Eyes.Changed += this.OnChangedEvent;
}
protected FileSystemWatcher Eyes { get; set; }
public event Action<string> Changed;
private void OnChangedEvent(object sender, FileSystemEventArgs eventArgs)
{
if (this.Changed == null)
{
return;
}
this.Changed(eventArgs.FullPath);
}
}
答案 0 :(得分:8)
你正在做的事情是不正确的 - 当你只使用模拟编写测试时,你并没有真正测试任何东西!
而你想要的是介绍一些非模拟代码,代码使用你用模拟代替的对象。
使用模拟的两件大事(特别是模拟框架,如moq)给你的是:
1 - 隔离
2 - 可验证性
通过隔离,我的意思是,在您的情况下,每次在文件复印机类上测试操作时,您都不希望真正复制文件。因此,您可以使用伪装成文件复制器的东西替换真正的文件复制器。
通过可证实性我的意思是,通常课程没有任何方式告诉你他们是否被召唤。这通常是一件好事,因为告诉其他人他们是否被调用不属于他们的工作,但在测试场景中你需要这些信息 - moq中的期望允许你收集它。
在这种情况下,看起来你有一些东西会引发一个事件,然后是一些侦听这个事件并在你的FileCopier上调用copy方法的东西。
因此,您希望模拟事件源(或以正确的方式调用事件的具体来源),然后引发该事件。
然后您需要第二个模拟 - FileCopier的模拟,期望使用正确的参数调用其复制方法。应该将此FileCopier模型传递给调用它的类(依赖注入),这样可以确认实际代码调用了复制方法。
答案 1 :(得分:3)
你只能有嘲笑,但这意味着你实际上没有测试任何东西。
在这种情况下,对copier
的引用会更好地成为真正的类,这样就可以在watchermock
关闭事件时测试事情发生。