1対ソリューションでWebAPIを単体テストまたはデバッグする方法はありますか?私はHttpClientを使用してWebAPIを使用しており、これを行うためにVSの2つのインスタンスがあります。
1つのVSインスタンスでは単体テストがあり、2番目のVSインスタンスではローカルホストでwebapiが実行されています。
これを行うためのより良い方法はありますか?
単体テストの好ましい方法は、WebAPIプロジェクトへの参照を持つことですか?
HttpClientを使用して使用したいので、UnitTestプロジェクトで参照する必要はありません。
したがって、私のUnitTestメソッドでは、baseAddressは " http:// localhost:1234 "になります。
これは、同じソリューションから起動された場合にWebAPIがホストされる場所です。
私がデバッグしている現在の方法では、同じソリューションをロードして2番目のVisual Studioインスタンスを起動し、一方をWebAPIプロジェクトで実行し、もう一方のVisualStudioで単体テストプロジェクトを実行する必要があります。
それで、同僚と私は、提案された答えを試してみましたが、役に立ちませんでした。ただし、テストでデバッグモードになったら、IISプロセスに接続することで、これに対する解決策が実際に見つかりました。手順は次のとおりです。
さらに簡単にするために、IISに自動的にアタッチするための拡張機能をダウンロードしました。これにより、[ツール]メニューにメニューバー項目が表示されます。
非常に簡単にするために、ツールバーセクションをカスタマイズしてメニューバーコマンドをツールバーに追加し、IISへのアタッチが1回クリックするだけで済むようにしました。
Daniel Mannが述べたように、これは単体テストではありません。これは統合テストです。プロジェクト全体を実行し、すべてをテストしています。
Webapiコントローラーの単体テストを行う場合は、単体テストプロジェクトをwebapiプロジェクトに追加し、単体テストを作成するだけです。一度に1つのクラスのみをテストすることに集中したいとします。そのクラスの依存関係をモック/偽造します。
これがMicrosoftの素晴らしい例です http://www.asp.net/web-api/overview/testing-and-debugging/unit-testing-with-aspnet-web-api
しかし、探しているのが単一のソリューションでのテストの実行である場合。両方のプロジェクトを同じソリューションに入れるだけです。ソリューションエクスプローラーでソリューションを右クリックします。 「スタートアッププロジェクトの設定」を選択します。 「複数のスタートアッププロジェクト」を選択し、同時にスタートアップしたいプロジェクトを選択します。
マイクが述べたように、WebAPIをセルフホストできます。
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
単体テストスイートを初期化するときにホスティングを開始し、テストスイートをクリーンアップするときにシャットダウンすることができます。
ASP.Net Coreの現在のバージョンでは、これに対する公式の解決策は、Microsoft.AspNetCore.TestHost Nuget Assemblyを使用して、テストプロジェクトでWebプロジェクトをホストするシミュレートされたWebサーバーを作成することです。
使用法の詳細はここで見つけることができます: https://docs.Microsoft.com/en-us/aspnet/core/testing/integration-testing
一方で、実際のWebサーバーが関与していない場合の本物の統合テストとはどのような定義であるかというと、少しファッジのように感じますが、セットアップすると、少なくともシームレスに機能します。
APIプロジェクトがあり、APIのエンドツーエンドの単体テストプロジェクトを作成した場合(つまり、HttpClient、WebClient、またはその他のhttpクライアントラッパーを使用してAPIを直接テストしている場合)、「複数のスタートアッププロジェクト」を有効にする必要があります。ソリューションに。以下の手順に従ってください。
セルフホストを試しましたが、いくつか問題が発生します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にアタッチ
次に、デバッグテストでブレークポイントを作成し、[デバッグ]> [プロセスにアタッチ]> [アタッチ]で選択します [OK]をクリックし、
iisexpressを検索し、[添付]をクリックします