繁体   English   中英

我正确使用嘲笑吗?

[英]Am I using mocks correctly?

我是第一次嘲笑和尝试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);
    }
}

你正在做的事情是不正确的 - 当你只使用嘲笑编写测试时,你并没有真正测试任何东西!

相反,你想要的是介绍一些非模拟代码,代码使用你用mocks替换的对象。

使用模拟的两件大事(特别是像moq这样的模拟框架)给你的是:

1 - 隔离

2 - 可验证性

隔离我的意思是,在您的情况下,每次在文件复制器类上测试操作时,您都不希望真正复制文件。 因此,您可以使用伪装成文件复印机的东西替换真正的文件复印机。

通过可证实性,我的意思是,通常课程没有任何方式告诉你他们是否被调用。 这通常是一件好事,因为告诉其他人他们是否被调用不是他们工作的一部分,但在测试场景中你需要这些信息 - moq的期望允许你收集它。


在这种情况下,看起来你有一些引发事件的东西,然后是一些侦听这个事件并在你的FileCopier上调用copy方法的东西。

因此,您希望模拟事件源(或以正确的方式调用事件的具体来源),然后引发该事件。

然后,您需要第二个模拟 - FileCopier的模拟,期望使用正确的参数调用其复制方法。 应该将此FileCopier模型传递给调用它的类(依赖注入),这允许您确认实际代码调用了复制方法。

你可以只有嘲笑,但这意味着你实际上没有测试任何东西。

在这种情况下,对copier的引用会更好地成为真正的类,这样你就可以测试当watchermock触发事件时发生的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM