How to debug/unit test webAPi in one solution

前端 未结 7 1843
借酒劲吻你
借酒劲吻你 2021-02-12 22:17

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

相关标签:
7条回答
  • 2021-02-12 22:37

    I try the selft hosted but I get some problens 1.

    HttpContext.Current is null
    
    1. I have in the web api custom error handler and in self hosted don't work

    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

    0 讨论(0)
  • 2021-02-12 22:39
    1. Start debugging Unit Test
    2. While on the first line of your test code or before calling your local web api project
    3. Right click on your web api project and Debug > Start new instance
    0 讨论(0)
  • 2021-02-12 22:39

    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.

    0 讨论(0)
  • 2021-02-12 22:40

    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:

    1. Ensure your unit-test project and Web API project are in the same solution.
    2. Ensure your solution is set single-startup in the properties section (i.e. leave as default).
    3. Add a breakpoint to the endpoint in your controller method that you want to debug.
    4. Add a breakpoint in your test that you want to debug and then right-click and hit "Debug Tests" (or use your favorite Test Runner like ReSharper to debug).
    5. Once your break point hits, click Debug | Attach to Process...
    6. Find and click on your local IIS process for the given service, then hit Attach
    7. Continue debugging and watch your breakpoint in your service get hit

    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.

    0 讨论(0)
  • 2021-02-12 22:46

    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.

    0 讨论(0)
  • 2021-02-12 22:46

    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:

    1. Right click on the solution file and select properties.
    2. Select "Multiple startup projects" radio button.
    3. Select the "Start" action in the drop-down for the web api project and unit test project.
    4. F5 to start in debug mode.
    5. You will get an error dialog saying "A project with an output type class library cannot be started directly". This is fine since the unit test project is just a class library (not an executable so there is no main/start method). Just click "Ok" the dialog.
    6. On the unit test method you want to test, right click and select "Debug Unit Tests" to start debugging.
    0 讨论(0)
提交回复
热议问题