Skip to content

Commit

Permalink
Add example of upgrading test host and WebApplicationFactory to .NET …
Browse files Browse the repository at this point in the history
…Core 3.0
  • Loading branch information
andrewlock committed Oct 29, 2019
1 parent cd5f8f6 commit 925a5ec
Show file tree
Hide file tree
Showing 118 changed files with 79,787 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="MartinCostello.Logging.XUnit" Version="0.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="2.2.0" />
<PackageReference Include="xunit" Version="2.4.0" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\ExampleApp2\ExampleApp2.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc.Testing;
using Microsoft.AspNetCore.TestHost;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Xunit.Abstractions;

namespace ExampleApp2.IntegrationTests
{
public class ExampleAppTestFixture : WebApplicationFactory<ExampleApp.Program>
{
public ITestOutputHelper Output { get; set; }

protected override IWebHostBuilder CreateWebHostBuilder()
{
var builder = base.CreateWebHostBuilder();
builder.ConfigureLogging(logging =>
{
logging.ClearProviders();
logging.AddXUnit(Output);
});

return builder;
}

protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureTestServices((services) =>
{
services.RemoveAll(typeof(IHostedService));
});
}

protected override void Dispose(bool disposing)
{
// Have to disable logging here as occurs
// outside a test context
Output = null;
base.Dispose(disposing);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;
using System.Net.Http;
using System.Threading.Tasks;
using Xunit;
using Xunit.Abstractions;

namespace ExampleApp2.IntegrationTests
{
public class HttpTests: IClassFixture<ExampleAppTestFixture>, IDisposable
{
readonly ExampleAppTestFixture _fixture;
readonly HttpClient _client;

public HttpTests(ExampleAppTestFixture fixture, ITestOutputHelper output)
{
_fixture = fixture;
fixture.Output = output;
_client = fixture.CreateClient();
}

public void Dispose() => _fixture.Output = null;

[Fact]
public async Task CanCallApi()
{
var result = await _client.GetAsync("/");

result.EnsureSuccessStatusCode();

var content = await result.Content.ReadAsStringAsync();

Assert.Contains("Welcome", content);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50589/",
"sslPort": 0
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"ExampleApp.IntegrationTests": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "http://localhost:50590/"
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.TestHost;
using Xunit;

namespace ExampleApp2.IntegrationTests
{
public class WebHostExampleTests
{
[Fact]
public async Task ShouldReturnHelloWorld()
{
// Arrange
var webHostBuilder = new WebHostBuilder()
.Configure(app => app.Run(async ctx =>
await ctx.Response.WriteAsync("Hello World!")
));

var server = new TestServer(webHostBuilder);
var client = server.CreateClient();

// Act
var response = await client.GetAsync("/");

// Assert
response.EnsureSuccessStatusCode();
var responseString = await response.Content.ReadAsStringAsync();
Assert.Equal("Hello World!", responseString);
}
}
}
15 changes: 15 additions & 0 deletions updating-test-host-to-3-0/2.0/ExampleApp2/ExampleApp2.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.2</TargetFramework>
<AspNetCoreHostingModel>InProcess</AspNetCoreHostingModel>
<RootNamespace>ExampleApp</RootNamespace>
</PropertyGroup>


<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
</ItemGroup>

</Project>
29 changes: 29 additions & 0 deletions updating-test-host-to-3-0/2.0/ExampleApp2/LoggingHostedService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace ExampleApp
{
public class LoggingHostedService : IHostedService
{
readonly ILogger<LoggingHostedService> _logger;

public LoggingHostedService(ILogger<LoggingHostedService> logger)
{
_logger = logger;
}

public async Task StartAsync(CancellationToken cancellationToken)
{
await Task.CompletedTask;
_logger.LogWarning("Starting service");
}

public async Task StopAsync(CancellationToken cancellationToken)
{
await Task.CompletedTask;
_logger.LogWarning("Stopping service");
}
}
}
26 changes: 26 additions & 0 deletions updating-test-host-to-3-0/2.0/ExampleApp2/Pages/Error.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
@page
@model ErrorModel
@{
ViewData["Title"] = "Error";
}

<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>

@if (Model.ShowRequestId)
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}

<h3>Development Mode</h3>
<p>
Swapping to the <strong>Development</strong> environment displays detailed information about the error that occurred.
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
23 changes: 23 additions & 0 deletions updating-test-host-to-3-0/2.0/ExampleApp2/Pages/Error.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace ExampleApp.Pages
{
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public class ErrorModel : PageModel
{
public string RequestId { get; set; }

public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);

public void OnGet()
{
RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
}
}
}
10 changes: 10 additions & 0 deletions updating-test-host-to-3-0/2.0/ExampleApp2/Pages/Index.cshtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@page
@model IndexModel
@{
ViewData["Title"] = "Home page";
}

<div class="text-center">
<h1 class="display-4">Welcome</h1>
<p>Learn about <a href="https://docs.microsoft.com/aspnet/core">building Web apps with ASP.NET Core</a>.</p>
</div>
17 changes: 17 additions & 0 deletions updating-test-host-to-3-0/2.0/ExampleApp2/Pages/Index.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace ExampleApp.Pages
{
public class IndexModel : PageModel
{
public void OnGet()
{

}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@page
@model PrivacyModel
@{
ViewData["Title"] = "Privacy Policy";
}
<h1>@ViewData["Title"]</h1>

<p>Use this page to detail your site's privacy policy.</p>
16 changes: 16 additions & 0 deletions updating-test-host-to-3-0/2.0/ExampleApp2/Pages/Privacy.cshtml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;

namespace ExampleApp.Pages
{
public class PrivacyModel : PageModel
{
public void OnGet()
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@using Microsoft.AspNetCore.Http.Features

@{
var consentFeature = Context.Features.Get<ITrackingConsentFeature>();
var showBanner = !consentFeature?.CanTrack ?? false;
var cookieString = consentFeature?.CreateConsentCookie();
}

@if (showBanner)
{
<div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert">
Use this space to summarize your privacy and cookie use policy. <a asp-page="/Privacy">Learn More</a>.
<button type="button" class="accept-policy close" data-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString">
<span aria-hidden="true">Accept</span>
</button>
</div>
<script>
(function () {
var button = document.querySelector("#cookieConsent button[data-cookie-string]");
button.addEventListener("click", function (event) {
document.cookie = button.dataset.cookieString;
}, false);
})();
</script>
}
Loading

0 comments on commit 925a5ec

Please sign in to comment.