0

背景:
在我正在开发的应用程序上,我正在使用 Visual Studio 2015、SpecFlow 和 ReSharper 2016.3 的混合体编写测试(我将其缩写为 R#,因为我很懒。)

我正在处理的应用程序基于模板发送 HTML 格式的电子邮件,这些电子邮件存储在 HTML 文件中,这些文件在 Visual Studio 2015 中设置为始终复制。

问题:
当我尝试运行测试时,出现以下异常:

System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\[Me]\AppData\Local\JetBrains\Installations\ReSharperPlatformVs14_001\Resources\SomeEmailTemplate.html`

该目录不是我正在处理的项目的输出目录,所以我仔细检查了我的 R# 设置,并确认 Shadow Copy 已关闭。非常清楚,我的 R# Shadow Copy 复选框确实未选中。

有问题的代码非常简单。TestContext.CurrentContext.TestDirectory由于应用程序本身需要此代码,因此我不能、不应该、甚至不想做正常的补救措施。将测试框架代码放在被测应用程序中是合适的。

public class HtmlTemplateLog : ISectionedLog, IRenderableLog
{
    #region Variables / Properties

    private readonly string _rawHtml;
    private readonly Dictionary<string, StringBuilder> _sectionDictionary = new Dictionary<string, StringBuilder>();

    private StringBuilder _workingSection;

    #endregion Variables / Properties

    #region Constructor

    public HtmlTemplateLog(string templateFile)
    {
        // This is specifically what breaks the tests.
        _rawHtml = File.ReadAllText(templateFile)
            .Replace("\r\n", string.Empty); // Replace all newlines with empty strings.
    }

    #endregion Constructor

    #region Methods

    // Methods work with the section dictionary.
    // The RenderLog method does a string.Replace on all section names in the HTML.
    // These methods aren't important for the question.

    #endregion Methods

如下例所示:

_someLog = new HtmlTemplateLog("Resources/SomeEmailTemplate.html");
// ...code...
_someLog.WriteLineInSection("{someSection}", "This is a message!");
string finalHtml = _someLog.RenderLog();

问题:
1. 我在 R# 测试中关闭了 Shadow Copy。为什么这还在做影子副本?
2. 鉴于这不是测试代码,因此我可以通过哪些方式解决 R# 不尊重 Shadow Copy 复选框的事实,因此通常适用于测试代码的补救措施不适用于这种情况?

4

1 回答 1

0

我已经找到了#2 的答案……不过,它相当笨拙。我受到@mcdon 对问题的不太详细版本的回答的启发。

几乎,如果我不想诉诸TestContext.CurrentContext.TestDirectory,那么我需要将我的本地文件名设置为绝对路径。不幸的是,R# 损坏的 Shadow Copy 设置创建了更多工作,因为我不能只询问当前正在执行的程序集——它会告诉我错误的事情。我需要进入代码库并询问它。

但是,当我们尝试在构建服务器上运行这段代码时,我仍然有点担心它是什么——我期待“意外”的结果。鉴于此,我想知道意外的结果是否真的可以称为意外,因为我预计这不会奏效......

无论如何,我想出的解决方法是这个字段属性系统:

private string _presentWorkingDirectory;
private string PresentWorkingDirectory
{
    get
    {
        if (!string.IsNullOrEmpty(_presentWorkingDirectory))
            return _presentWorkingDirectory;

        var assembly = Assembly.GetExecutingAssembly();
        var codebase = new Uri(assembly.CodeBase);
        var filePath = codebase.LocalPath;
        var path = Directory.GetParent(filePath);
        _presentWorkingDirectory = path.ToString();

        return _presentWorkingDirectory;
    }
}
于 2017-02-17T16:15:52.390 回答