Skip to content

Commit 236aded

Browse files
authored
Integration tests documentation add nunit mstest (#35328)
1 parent efc2d52 commit 236aded

15 files changed

+1701
-27
lines changed

aspnetcore/test/integration-tests.md

+196-13
Large diffs are not rendered by default.

aspnetcore/test/integration-tests/includes/integration-tests9.md

+196-14
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System.Data.Common;
2+
using Microsoft.AspNetCore.Hosting;
3+
using Microsoft.AspNetCore.Mvc.Testing;
4+
using Microsoft.Data.Sqlite;
5+
using Microsoft.EntityFrameworkCore;
6+
using Microsoft.EntityFrameworkCore.Infrastructure;
7+
using Microsoft.Extensions.DependencyInjection;
8+
using RazorPagesProject.Data;
9+
10+
namespace RazorPagesProject.Tests;
11+
12+
// <snippet1>
13+
public class CustomWebApplicationFactory<TProgram>
14+
: WebApplicationFactory<TProgram> where TProgram : class
15+
{
16+
protected override void ConfigureWebHost(IWebHostBuilder builder)
17+
{
18+
builder.ConfigureServices(services =>
19+
{
20+
var dbContextDescriptor = services.SingleOrDefault(
21+
d => d.ServiceType ==
22+
typeof(IDbContextOptionsConfiguration<ApplicationDbContext>));
23+
24+
services.Remove(dbContextDescriptor);
25+
26+
var dbConnectionDescriptor = services.SingleOrDefault(
27+
d => d.ServiceType ==
28+
typeof(DbConnection));
29+
30+
services.Remove(dbConnectionDescriptor);
31+
32+
// Create open SqliteConnection so EF won't automatically close it.
33+
services.AddSingleton<DbConnection>(container =>
34+
{
35+
var connection = new SqliteConnection("DataSource=:memory:");
36+
connection.Open();
37+
38+
return connection;
39+
});
40+
41+
services.AddDbContext<ApplicationDbContext>((container, options) =>
42+
{
43+
var connection = container.GetRequiredService<DbConnection>();
44+
options.UseSqlite(connection);
45+
});
46+
});
47+
48+
builder.UseEnvironment("Development");
49+
}
50+
}
51+
// </snippet1>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
using System.Net;
2+
using System.Net.Http.Headers;
3+
using System.Security.Claims;
4+
using System.Text.Encodings.Web;
5+
using AngleSharp.Html.Dom;
6+
using Microsoft.AspNetCore.Authentication;
7+
using Microsoft.AspNetCore.Mvc.Testing;
8+
using Microsoft.AspNetCore.TestHost;
9+
using Microsoft.Extensions.DependencyInjection;
10+
using Microsoft.Extensions.Logging;
11+
using Microsoft.Extensions.Options;
12+
using RazorPagesProject.Services;
13+
using RazorPagesProject.Tests.Helpers;
14+
15+
namespace RazorPagesProject.Tests.IntegrationTests;
16+
17+
[TestClass]
18+
public class AuthTests
19+
{
20+
21+
private static CustomWebApplicationFactory<Program> _factory;
22+
23+
[ClassInitialize]
24+
public static void AssemblyInitialize(TestContext _)
25+
{
26+
_factory = new CustomWebApplicationFactory<Program>();
27+
}
28+
29+
[ClassCleanup(ClassCleanupBehavior.EndOfClass)]
30+
public static void AssemblyCleanup(TestContext _)
31+
{
32+
_factory.Dispose();
33+
}
34+
35+
// <snippet1>
36+
[TestMethod]
37+
public async Task Get_GithubProfilePageCanGetAGithubUser()
38+
{
39+
// Arrange
40+
void ConfigureTestServices(IServiceCollection services) =>
41+
services.AddSingleton<IGithubClient>(new TestGithubClient());
42+
var client = _factory
43+
.WithWebHostBuilder(builder =>
44+
builder.ConfigureTestServices(ConfigureTestServices))
45+
.CreateClient();
46+
47+
// Act
48+
var profile = await client.GetAsync("/GithubProfile");
49+
Assert.AreEqual(HttpStatusCode.OK, profile.StatusCode);
50+
var profileHtml = await HtmlHelpers.GetDocumentAsync(profile);
51+
52+
var profileWithUserName = await client.SendAsync(
53+
(IHtmlFormElement)profileHtml.QuerySelector("#user-profile"),
54+
new Dictionary<string, string> { ["Input_UserName"] = "user" });
55+
56+
// Assert
57+
Assert.AreEqual(HttpStatusCode.OK, profileWithUserName.StatusCode);
58+
var profileWithUserHtml =
59+
await HtmlHelpers.GetDocumentAsync(profileWithUserName);
60+
var userLogin = profileWithUserHtml.QuerySelector("#user-login");
61+
Assert.AreEqual("user", userLogin.TextContent);
62+
}
63+
64+
public class TestGithubClient : IGithubClient
65+
{
66+
public Task<GithubUser> GetUserAsync(string userName)
67+
{
68+
if (userName == "user")
69+
{
70+
return Task.FromResult(
71+
new GithubUser
72+
{
73+
Login = "user",
74+
Company = "Contoso Blockchain",
75+
Name = "John Doe"
76+
});
77+
}
78+
else
79+
{
80+
return Task.FromResult<GithubUser>(null);
81+
}
82+
}
83+
}
84+
// </snippet1>
85+
86+
// <snippet2>
87+
[TestMethod]
88+
public async Task Get_SecurePageRedirectsAnUnauthenticatedUser()
89+
{
90+
// Arrange
91+
var client = _factory.CreateClient(
92+
new WebApplicationFactoryClientOptions
93+
{
94+
AllowAutoRedirect = false
95+
});
96+
97+
// Act
98+
var response = await client.GetAsync("/SecurePage");
99+
100+
// Assert
101+
Assert.AreEqual(HttpStatusCode.Redirect, response.StatusCode);
102+
StringAssert.StartsWith(response.Headers.Location.OriginalString, "http://localhost/Identity/Account/Login");
103+
}
104+
// </snippet2>
105+
106+
// <snippet3>
107+
[TestMethod]
108+
public async Task Get_SecurePageIsReturnedForAnAuthenticatedUser()
109+
{
110+
// Arrange
111+
var client = _factory.WithWebHostBuilder(builder =>
112+
{
113+
builder.ConfigureTestServices(services =>
114+
{
115+
services.AddAuthentication(defaultScheme: "TestScheme")
116+
.AddScheme<AuthenticationSchemeOptions, TestAuthHandler>(
117+
"TestScheme", options => { });
118+
});
119+
})
120+
.CreateClient(new WebApplicationFactoryClientOptions
121+
{
122+
AllowAutoRedirect = false,
123+
});
124+
125+
client.DefaultRequestHeaders.Authorization =
126+
new AuthenticationHeaderValue(scheme: "TestScheme");
127+
128+
//Act
129+
var response = await client.GetAsync("/SecurePage");
130+
131+
// Assert
132+
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
133+
}
134+
// </snippet3>
135+
}
136+
137+
// <snippet4>
138+
public class TestAuthHandler : AuthenticationHandler<AuthenticationSchemeOptions>
139+
{
140+
public TestAuthHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
141+
ILoggerFactory logger, UrlEncoder encoder)
142+
: base(options, logger, encoder)
143+
{
144+
}
145+
146+
protected override Task<AuthenticateResult> HandleAuthenticateAsync()
147+
{
148+
var claims = new[] { new Claim(ClaimTypes.Name, "Test user") };
149+
var identity = new ClaimsIdentity(claims, "Test");
150+
var principal = new ClaimsPrincipal(identity);
151+
var ticket = new AuthenticationTicket(principal, "TestScheme");
152+
153+
var result = AuthenticateResult.Success(ticket);
154+
155+
return Task.FromResult(result);
156+
}
157+
}
158+
// </snippet4>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
namespace RazorPagesProject.Tests.IntegrationTests;
2+
3+
// <snippet1>
4+
[TestClass]
5+
public class BasicTests
6+
{
7+
private static CustomWebApplicationFactory<Program> _factory;
8+
9+
[ClassInitialize]
10+
public static void AssemblyInitialize(TestContext _)
11+
{
12+
_factory = new CustomWebApplicationFactory<Program>();
13+
}
14+
15+
[ClassCleanup(ClassCleanupBehavior.EndOfClass)]
16+
public static void AssemblyCleanup(TestContext _)
17+
{
18+
_factory.Dispose();
19+
}
20+
21+
[TestMethod]
22+
[DataRow("/")]
23+
[DataRow("/Index")]
24+
[DataRow("/About")]
25+
[DataRow("/Privacy")]
26+
[DataRow("/Contact")]
27+
public async Task Get_EndpointsReturnSuccessAndCorrectContentType(string url)
28+
{
29+
// Arrange
30+
var client = _factory.CreateClient();
31+
32+
// Act
33+
var response = await client.GetAsync(url);
34+
35+
// Assert
36+
response.EnsureSuccessStatusCode(); // Status Code 200-299
37+
Assert.AreEqual("text/html; charset=utf-8",
38+
response.Content.Headers.ContentType.ToString());
39+
}
40+
}
41+
// </snippet1>

0 commit comments

Comments
 (0)