此单元测试是否正确实施?

时间:2018-10-12 11:19:11

标签: c# unit-testing

我有一个单元测试,旨在检查访问权限,并在构造类之前确保对文件系统有足够的访问权限。但是,我认为我的单元测试违反了单元测试原理(FIRST),例如:隔离/独立和透彻,它们谈论建立独立的单元测试,并且还考虑了故障场景的多个方面。我还认为,这种实现方式的单元测试是对.Net框架进行单元测试,而不是对我编写的代码的功能进行测试,因为未对基础类进行模拟。但是我也想知道您的意见,看看我有多对错。

单元测试的说明:

单元测试试图确保EventFeedFile的构造函数正在执行一种检查访问权限的方法。该方法称为VerifyWritable()。请注意,EventFeedFile是一个单独的班级,VerifyWritable()是另一个班级的席位。

[Test]
public void DirectoryNotWritableTest()
{
    var tempPath = Path.Combine(Path.GetTempPath(), "EventFileDirectoryWriteDeniedTest");
    int pageSize = 10;

    try
    {
        if (Directory.Exists(tempPath))
            Directory.Delete(tempPath, true);

        var directoryInfo = Directory.CreateDirectory(tempPath);
        var securityRules = directoryInfo.GetAccessControl();
        var writeDeniedRule =
            new FileSystemAccessRule("Everyone", FileSystemRights.CreateFiles, AccessControlType.Deny);
        securityRules.AddAccessRule(writeDeniedRule);
        directoryInfo.SetAccessControl(securityRules);

        // ReSharper disable once ObjectCreationAsStatement
        Assert.Throws<UnauthorizedAccessException>(() => new EventFeedFile(new PersistenceDirectory(tempPath),
            pageSize));
    }
    finally
    {
        if (Directory.Exists(tempPath))
            Directory.Delete(tempPath, true);
    }
}

/// <param name="directory">The directory containing the persistence file.</param>
/// <param name="pageSize">The size of event feed page.</param>
public EventFeedFile(PersistenceDirectory directory, int pageSize)
{
    directory.EnsureExists();
    directory.VerifyWritable();
    mParentDirectory = directory.TargetPath;
    mFullName = Path.Combine(mParentDirectory, Constants.FILE_NAME_EVENTPERSISTENCE);
    mPageSize = pageSize;
}

public void VerifyWritable()
{
    using (File.Create(
        Path.Combine(TargetPath, Path.GetRandomFileName()),
        1024,
        FileOptions.DeleteOnClose))
    {
    }
}

3 个答案:

答案 0 :(得分:5)

正如您所说,您正在测试EventFeedFile
您还说过VerifyWritable在另一个模块中。

然后很明显VerifyWritable()应该被嘲笑为分别返回抛出以达到测试目的。
而不是做两件事:

  1. 在不需要时测试VerifyWritable代码。
    万一发生故障,您的测试将在范围外的代码上失败(或更糟糕的是,将通过错误的代码)。

  2. 您实际上是在写文件,而我认为不好的做法是访问规则,伸缩性很差,并且在切换FileSystems / OperatingSystems(或版本)时可能会更改

注意::该测试实际上并没有测试.NET Framework,它只是利用真实环境,而不是创建供测试使用的模拟(虚拟环境)。

答案 1 :(得分:2)

我认为这里没有明确的是/否答案。

单元测试不应访问文件系统等外部数据。但是好吧,在某个时候,您必须对其进行测试,并且如果自动执行此操作的方法是VS中的单元测试项目,那就可以了。将名称留给纯粹主义者,我对自动化测试感到满意。

是的,是的,被测试的代码是纯.NET Framework。是的,它正在测试框架。 但是它也在测试是否有人真的使用该框架来完成这项工作。如果要求在构造上而不是在过程的后期抛出该异常,那么这是一个有效的测试。如果有人弄乱了代码并引入了错误,则此测试将找到它。

所以我想说这是一个很好的测试。最好先删除它。这样可以确保正确执行检查可访问性的要求。

答案 2 :(得分:0)

感谢大家提供的好意见。最后,我也想说一下我自己的观点:该测试存在几个问题。我将尝试在此处简短列出:

  1. 在写/读时必须进行访问写检查 时间,谁知道在创建类和开始使用 写/读方法看起来像那个访问权限。另外,什么 构造类后,访问权限是否由于任何原因发生了变化。
  2. VerifyWritable方法来自另一个类,应该是 在EventFeedFile类中被嘲笑。
  3. 如果我们不检查怎么办 有访问权限吗?最后由于 UnauthorizedAccessException,并且由于我们没有对此进行总结 异常与另一个应用程序异常或采取任何具体措施 诸如正确记录日志之类的操作。测试将变得毫无用处。 (这就是为什么我说这是对.Net框架进行单元测试的原因。)
  4. 从功能的角度来看,仅在构建时检查访问权限是不够的,而且访问权限的检查方法也很模糊