【问题标题】:Directory.GetCurrentDirectory Throwing System.IO.DirectoryNotFoundException in unit testsDirectory.GetCurrentDirectory 在单元测试中引发 System.IO.DirectoryNotFoundException
【发布时间】:2021-12-09 11:06:39
【问题描述】:

当我正在测试的函数使用 Directory.GetCurrentDirectory() 时,我再次收到以下错误:System.IO.DirectoryNotFoundException

我想知道是否存在模拟方法或更改 Directory.GetCurrentDirectory() 返回的方法。我愿意接受建议..

我无法发布完整的代码,但它是这样的:

[Fact]
public async Task someMethod()
{
    // Arrange
    var userData = new userData
    {
        Email = "test@test.com"
    };

    _someRepository.Setup(x => x.GetSomething(It.IsAny<string>())).ReturnsAsync(Faker());

    var service= new Service();

    // Act
    var result = await service.TestedMethod(userData);

    // Assert
    Assert.False(result.Success);
}

public class Service
{

    public async Task<ReponseViewModel> TestedMethod(userData vm)
    {
        var anything = await _someRepository.GetSomething(vm.Email);
        
        var template = GetTemplate(url);

        return something;
    }

    private string GetTemplate(string url)
    {
        var template = File.ReadAllText(
                        Path.Combine(
                            Directory.GetCurrentDirectory(),
                            "wwwroot",
                            "html",
                            "myfile.html"));

        return template;
    }
}

【问题讨论】:

  • 抽象出与 System.IO 的紧密耦合
  • 可能,单元测试运行程序是从与您预期不同的目录执行的。这就是Directory.GetCurrentDirectory() 方法返回错误路径的原因。您可以尝试调试单元测试来验证这一点
  • 您确定异常来自Directory.GetCurrentDirectory() 而不是File.ReadAllText()

标签: c# .net unit-testing moq xunit


【解决方案1】:

问题可能是单元测试运行程序是从与项目输出目录不同的位置执行的。这就是为什么Directory.GetCurrentDirectory() 方法可以返回您的代码不期望的路径。

如果测试程序集与生产程序集位于同一文件夹中,您可以尝试修改 GetTemplate(string url) 方法以获取执行程序集位置,而不是尝试获取当前目录:

private string GetTemplate(string url)
{
    var assemblyPath = Assembly.GetExecutingAssembly().Location;
    var template = File.ReadAllText(
                    Path.Combine(
                        assemblyPath,
                        "wwwroot",
                        "html",
                        "myfile.html"));

    return template;
}

如果执行程序集没有帮助,请尝试Assembly.GetAssembly(Type type) 版本。对于type 参数,您可以尝试生产程序集中的任何类型。

另一个建议是获取并提供模板的相对或绝对路径。

【讨论】:

  • 这可能会修复测试,但也可能会通过引入当前目录是启动程序集所在目录的假设来破坏代码。
  • @CodeCaster 是的。该测试看起来更像是一个集成测试(不是纯粹的单元测试),因为它使用模板等真实资源。使用测试程序集可直接访问的模拟模板将是首选解决方案
  • 是的,无论如何,你的答案中有一个警告,请投赞成票。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-29
  • 2012-11-30
  • 2010-09-19
  • 1970-01-01
相关资源
最近更新 更多