Is there a way to unit test or debug a web api in one vs solution? I am consuming the WebAPI using HttpClient and have two instances of VS up to do this.
in 1 VS instan
I try the selft hosted but I get some problens 1.
HttpContext.Current is null
IisExpress solution work for me very good
bathe file to deploy to 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
I work with 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();
}
}
attach to iisexpress
Debug test then make a breakpoint goto Debug>Attach to process> in the attach to select click OK,
search iisexpress and click attach
You can self host the web api as mike mentioned,
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();
}
for more details, http://www.asp.net/web-api/overview/older-versions/self-host-a-web-api
you could start the hosting when you initialize your unit test suite, and shutdown when you cleanup the test suite.
So a colleague and I just tried the suggested answers to no avail. However, we have actually found a solution to this that works well by attaching to the IIS process once you are in debug mode on your test. Here are the steps:
For extra ease, we downloaded an extension for attaching to IIS automatically which gave us a menubar item in the Tools menu.
For superb ease we customized the toolbar section to add the menubar command to the toolbar so that attaching to IIS was one simple click.
As Daniel Mann stated, this isn't unit testing. This is integration testing. You are running up the entire project and testing everything.
If you want to unit test you webapi controllers, just add a unit test project to webapi project and create unit tests. You want to focus on testing only a single class at a time. Mock/Fake any dependencies of that class.
Here's a nice example from Microsoft http://www.asp.net/web-api/overview/testing-and-debugging/unit-testing-with-aspnet-web-api
but if what you are looking for is running the test you have in a single solution. Just put both projects in the same solution. Right click on the solution in the solution explorer. Select "Set StartUp projects." select "multiple startup projects" and select the projects you want to startup at the same time.
If you have an API project and you created an end-to-end unit test project for the API (meaning you are testing the API directly using HttpClient, WebClient, or other http client wrappers), you have to enable "Multiple startup projects" on the solution. Follow steps below: