简体   繁体   中英

App Resources breaking in unit tests, due to uncontrollable shadow copying from ReSharper

Background:
On an application I am working on, I am writing tests using a mixture of Visual Studio 2015, SpecFlow, and ReSharper 2016.3 (I'll abbreviate this as R#, because I'm lazy.)

The application I am working on sends HTML-formatted emails, based on a template, which are stored in HTML files that are set as Copy Always in Visual Studio 2015.

Problem:
When I attempt to run my tests, I get the following exception:

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

The directory was not the output directory of the project I am working on, so I double-checked my R# settings, and confirmed that Shadow Copy was turned off . To be perfectly clear, my R# Shadow Copy checkbox is indeed unchecked.

The offending code is really pretty simple. Normal remedies like TestContext.CurrentContext.TestDirectory is not something I can, should, or even want to do, due to the fact that this code is needed by the application itself. It would be in appropriate to put test framework code in the application under test.

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

This is invoked as in the example below:

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

Questions:
1. I've turned off Shadow Copy on my R# tests. Why is this still doing Shadow Copies?
2. In what ways can I work around the fact that R# is not respecting the Shadow Copy checkbox, given that this is not test code , and thus that remedies that would normally be appropriate for test code aren't for this case?

I've discovered an answer for #2...though, it's rather clunky. I was inspired by the answer from @mcdon for a less-detailed version of the question .

Pretty much, if I don't want to resort to TestContext.CurrentContext.TestDirectory , then I need to make my local filenames into absolute paths. Unfortunately, R#'s broken Shadow Copy setting creates more work, since I can't just interrogate the currently-executing assembly - it will tell me the wrong thing. I need to get at the codebase instead and interrogate that.

I'm still a bit worried about what this code when we try to run it on the build server, however - I'm expecting 'unexpected' results. In that light, I'm wondering if the unexpected results can truly be called unexpected, given that I'm expecting that this won't work...

Anyways, the fix I came up with was this field-property system:

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;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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