有没有办法在一个vs解决方案中对web api进行单元测试或调试?我正在使用HttpClient使用WebAPI并且有两个VS实例来执行此操作。
在1个VS实例中我有单元测试,在第二个vs实例中我有在localhost中运行的webapi。
有更好的方法吗?
单元测试的首选方法是引用WebAPI项目吗?
我想使用httpClient来使用它,而不必在UnitTest项目中引用它。
所以在我的UnitTest方法中,它的baseAddress为“http://localhost:1234”
这将是托管从同一解决方案启动的WebAPI的地方。
我正在调试的当前方式要求我启动第二个Visual Studio实例并加载相同的解决方案,并运行WebAPI项目,而另一个Visual Studio运行单元测试项目。
答案 0 :(得分:8)
答案 1 :(得分:4)
Daniel Mann表示,这不是单元测试。这是集成测试。您正在运行整个项目并测试所有内容。
如果要对webapi控制器进行单元测试,只需将单元测试项目添加到webapi项目并创建单元测试。您希望一次只关注一个类。模拟/伪造该类的任何依赖项。
以下是Microsoft http://www.asp.net/web-api/overview/testing-and-debugging/unit-testing-with-aspnet-web-api
的一个很好的例子但是如果您正在寻找的是在单一解决方案中运行测试。只需将两个项目放在同一个解决方案中。右键单击解决方案资源管理器中的解决方案。选择"设置启动项目。"选择"多个启动项目"并选择要同时启动的项目。
答案 2 :(得分:4)
所以一位同事和我刚试过建议的答案都无济于事。但是,我们实际上已经找到了一个解决方案,通过在测试时处于调试模式时附加到IIS进程,可以很好地解决这个问题。以下是步骤:
为了方便起见,我们下载了一个自动附加到IIS的扩展程序,它在“工具”菜单中为我们提供了一个菜单栏项。
为了方便起见,我们自定义了工具栏部分,将menubar命令添加到工具栏中,以便只需点击一下即可附加到IIS。
答案 3 :(得分:1)
你可以像迈克提到的那样自我托管网络API,
var config = new HttpSelfHostConfiguration("http://localhost:8080");
config.Routes.MapHttpRoute(
"API Default", "api/{controller}/{id}",
new { id = RouteParameter.Optional });
using (HttpSelfHostServer server = new HttpSelfHostServer(config))
{
server.OpenAsync().Wait();
Console.WriteLine("Press Enter to quit.");
Console.ReadLine();
}
了解更多详情, http://www.asp.net/web-api/overview/older-versions/self-host-a-web-api
您可以在初始化单元测试套件时启动托管,并在清理测试套件时关闭。
答案 4 :(得分:0)
如果您有一个API项目并且您为API创建了一个端到端的单元测试项目(意味着您正在使用HttpClient,WebClient或其他http客户端包装器直接测试API),则必须启用&# 34;多个启动项目"在解决方案上。请按照以下步骤操作:
答案 5 :(得分:0)
在当前版本的ASP.Net Core中,官方解决方案是使用Microsoft.AspNetCore.TestHost Nuget程序集,该程序集在测试项目中创建托管Web项目的模拟Web服务器。
有关使用的详细信息,请访问: https://docs.microsoft.com/en-us/aspnet/core/testing/integration-testing
一方面它感觉有点像软糖,因为如果不涉及真正的网络服务器,它的真正集成测试是什么定义,另一方面,一旦你设置了它,它至少可以非常无缝地工作
答案 6 :(得分:0)
我尝试托管的selft,但是遇到了一些问题 1.
HttpContext.Current is null
IisExpress解决方案对我来说非常好
保存文件以部署到iis
@Echo off
set msBuildDir=C:\Program Files (x86)\MSBuild\14.0\Bin
::compile web api project
call "%msBuildDir%\msbuild.exe" solutionFilePath.sln /t:projectName /p:Configuration=Debug;TargetFrameworkVersion=v4.5 /l:FileLogger,Microsoft.Build.Engine;logfile=Manual_MSBuild_ReleaseVersion_LOG.log /p:Platform="Any CPU" /p:BuildProjectReferences=false
call "C:\Program Files (x86)\IIS Express\iisexpress.exe" /path:"pathToRootOfApiProject" /port:8888 /trace:error
我正在使用Nunit frameWork
[SetUpFixture]
public class SetUpTest
{
private Process process = null;
private Process IisProcess = null;
private System.IO.StreamWriter sw = null;
string programsFilePath = Environment.GetEnvironmentVariable(@"PROGRAMFILES(X86)");
[OneTimeSetUp]
public void Initialize()
{
//compile web api project
List<string> commands = new List<string>();
commands.Add($@"CD {programsFilePath}\MSBuild\14.0\Bin\");
commands.Add($@"msbuild ""pathToYourSolution.sln"" /t:ProjrctName /p:Configuration=Debug;TargetFrameworkVersion=v4.5 /p:Platform=""Any CPU"" /p:BuildProjectReferences=false /p:VSToolsPath=""{programsFilePath}\MSBuild\Microsoft\VisualStudio\v14.0""");
RunCommands(commands);
//deploy to iis express
RunIis();
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
if (IisProcess.HasExited == false)
{
IisProcess.Kill();
}
}
void RunCommands(List<string> cmds, string workingDirectory = "")
{
if (process == null)
{
InitializeCmd(workingDirectory);
sw = process.StandardInput;
}
foreach (var cmd in cmds)
{
sw.WriteLine(cmd);
}
}
void InitializeCmd(string workingDirectory = "")
{
process = new Process();
var psi = new ProcessStartInfo();
psi.FileName = "cmd.exe";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
psi.WorkingDirectory = workingDirectory;
process.StartInfo = psi;
process.Start();
process.OutputDataReceived += (sender, e) => { Debug.WriteLine($"cmd output: {e.Data}"); };
process.ErrorDataReceived += (sender, e) => { Debug.WriteLine($"cmd output: {e.Data}"); throw new Exception(e.Data); };
process.BeginOutputReadLine();
process.BeginErrorReadLine();
}
void RunIis()
{
string _port = System.Configuration.ConfigurationManager.AppSettings["requiredPort"];
if (_port == 0)
{
throw new Exception("no value by config setting for 'requiredPort'");
}
IisProcess = new Process();
var psi = new ProcessStartInfo();
psi.FileName = $@"{programsFilePath}\IIS Express\iisexpress.exe";
psi.Arguments = $@"/path:""pathToRootOfApiProject"" /port:{_port} /trace:error";
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
IisProcess.StartInfo = psi;
IisProcess.Start();
IisProcess.OutputDataReceived += (sender, e) => { Debug.WriteLine($"cmd output: {e.Data}"); };
IisProcess.ErrorDataReceived += (sender, e) =>
{
Debug.WriteLine($"cmd output: {e.Data}");
if (e.Data != null)
{
throw new Exception(e.Data);
}
};
IisProcess.BeginOutputReadLine();
IisProcess.BeginErrorReadLine();
}
}
附加到iisexpress
调试测试,然后创建一个断点 转到调试>附加到进程> 在附件中选择 单击确定,
搜索iisexpress,然后单击附加