尝试从xunit项目的调试文件夹启动exe时出错。
A fatal error was encountered. The library 'hostpolicy.dll' required to execute the application was not found in 'C:Program Filesdotnet'.
Failed to run as a self-contained app.
- The application was run as a self-contained app because 'C:UsersmeDesktopdotnet-testing-cli-issueMyApp.Console.TestsbinDebugnet7.0MyApp.Console.runtimeconfig.json' did not specify a framework.
- If this should be a framework-dependent app, specify the appropriate framework in 'C:UsersmeDesktopdotnet-testing-cli-issueMyApp.Console.TestsbinDebugnet7.0MyApp.Console.runtimeconfig.json'.
MyApp.Console.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
</PropertyGroup>
</Project>
Program.cs
// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");
MyApp.Console.Tests.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
<IsTestProject>true</IsTestProject>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="CliWrap" Version="3.6.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..MyApp.ConsoleMyApp.Console.csproj" />
</ItemGroup>
</Project>
Tests.cs
public class UnitTest1
{
[Fact]
public async Task Test1Async()
{
var result = await Cli.Wrap("MyApp.Console.exe")
.WithArguments(new[] { "--foo", "bar" })
.ExecuteAsync();
}
}
完整复制:https://github.com/VictorioBerra/netcore-console-test-exe
这也可能是一个X-Y问题。我想测试我的控制台应用程序,包括一个使用通用主机,appsettings, the works的应用程序。
我如何启动和测试它?
如果您将构建解决方案并打开"MyApp.Console.TestsbinDebugnet7.0"one_answers"MyApp.Console.Tests bin 调试 net7.0"文件夹和比较内容,你会发现后者比前者拥有更多的文件——这些文件是自包含应用程序附带的运行时的一部分,并且是运行它所必需的。你可以设置一些复杂的构建操作来执行正确的应用程序发布到某个路径,并在测试项目中使用它,但我认为这种方法太复杂,而且可能太脆弱。
你可以切换到"old"Program.Main
样式(如果项目是用dotnet new console
CLI命令创建的-提供--use-program-main
,因此无需手动更改),运行Program.Main(args)
,然后捕获"当前";控制台通过Console.Out
输出:
public sealed class ConsoleCapture : IDisposable
{
private readonly StringWriter _stringWriter = new();
private readonly TextWriter _oldOut;
private readonly TextWriter _oldErr;
public ConsoleCapture()
{
_oldOut = Console.Out;
_oldErr = Console.Error;
Console.SetOut(_stringWriter);
Console.SetError(_stringWriter);
}
public string GetAll()
{
return _stringWriter.ToString();
}
public void Dispose()
{
Console.SetOut(_oldOut);
Console.SetError(_oldErr);
_stringWriter.Dispose();
}
}
和用法:
using var console = new ConsoleCapture();
var res = Program.Main(args);
var consoleOutput = console.GetAll();
Assert.AreEqual(expectedExitCode, res);
Assert.Contains("Hello World", res);
以示例打开PR。
指出:
- ASP。在。NET Core应用中,使用集成测试方法甚至更容易——查看这个答案了解一些细节(上面的所有内容都不需要)
- 如果你仍然想保留顶级语句
Program
文件,那么你可以做一些反射来调用生成的Program.<Main>$
,尽管这会有点脆弱,因为生成模式可以改变(尽管有一个选项可以通过使用Assembly.EntryPoint
来减轻这种情况-参见这个答案)。 至于配置,请注意,. net中的内置配置支持多个提供者,并使用分层方法。您可以在测试项目中复制(或将其作为主项目的链接添加)appsettings文件(尽管通常您将拥有一个独立的appsettings文件)和/或提供config作为CLI参数(这里有一些示例)