Skip to main content

test-mvc-razor-ui

Write ABP MVC/Razor integration tests that drive real HTTP against the app through AbpWebApplicationFactoryIntegratedTest. USE FOR: subclassing AbpWebApplicationFactoryIntegratedTest with the SUT Program type (not a module); the Client (AllowAutoRedirect is false, so unauthenticated requests return 302); GetRequiredService/GetService/GetUrl; the per-solution GetResponseAsStringAsync/GetResponseAsObjectAsync/GetResponseAsync helpers (Shouldly-based, copied into the WebTestBase — not shipped in any NuGet package); the web test module (DependsOn AbpAspNetCoreTestBaseModule plus the SUT web module, the CompiledRazorAssemblyPart registration, and the OpenIddict dev certificate); and faking a logged-in user with the FakeAuthentication scheme plus FakeUserClaims pushing an AbpClaimTypes.UserId claim. DO NOT USE FOR: application-service/repository integration tests (test-abp-applications); Angular component tests (test-angular-ui); production hosting/middleware configuration (configure-production-hosting).

Jump to install

Source facts

Repository
abpframework/abp-skills
Last source activity
July 20, 2026 at 03:24
Detected SKILL.md language
English
Stars
18
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
test-mvc-razor-ui
description
Write ABP MVC/Razor integration tests that drive real HTTP against the app through AbpWebApplicationFactoryIntegratedTest. USE FOR: subclassing AbpWebApplicationFactoryIntegratedTest with the SUT Program type (not a module); the Client (AllowAutoRedirect is false, so unauthenticated requests return 302); GetRequiredService/GetService/GetUrl; the per-solution GetResponseAsStringAsync/GetResponseAsObjectAsync/GetResponseAsync helpers (Shouldly-based, copied into the WebTestBase — not shipped in any NuGet package); the web test module (DependsOn AbpAspNetCoreTestBaseModule plus the SUT web module, the CompiledRazorAssemblyPart registration, and the OpenIddict dev certificate); and faking a logged-in user with the FakeAuthentication scheme plus FakeUserClaims pushing an AbpClaimTypes.UserId claim. DO NOT USE FOR: application-service/repository integration tests (test-abp-applications); Angular component tests (test-angular-ui); production hosting/middleware configuration (configure-production-hosting).
license
MIT
# Test MVC / Razor UI (ABP) ABP's `Volo.Abp.AspNetCore.TestBase` boots the real web app in-process so you can request pages/endpoints over HTTP and assert on the response. This is the ASP.NET Core web counterpart to the application-layer `*TestBase` chain. ## When to Use - Requesting an MVC action or Razor page over HTTP and asserting on the HTML/JSON. - Verifying routing, an authenticated page, or an anonymous 302-to-login. ## When Not to Use - **Application services, domain services, repositories** — use **test-abp-applications** (no web host needed). - **Angular component tests** — use **test-angular-ui**. - **Configuring production hosting/middleware** — use **configure-production-hosting**. ## The test base Subclass `AbpWebApplicationFactoryIntegratedTest<TProgram>` where `TProgram` is the **SUT's `Program` entry-point class**, not an ABP module. It gives you `Client` (an `HttpClient` with **`AllowAutoRedirect = false`**, so an unauthenticated request returns a `302`, not the login page body), plus `GetService<T>` / `GetRequiredService<T>` / `GetUrl<TController>()`. The `GetResponseAs*` helpers the ABP docs show are **not in the package** — each solution copies them into its own `*WebTestBase` (they use Shouldly). Put them there: ```csharp using System.Net; using System.Text.Json; using Shouldly; using Volo.Abp.AspNetCore.TestBase; using MyCompanyName.MyProjectName.Web; // the SUT's Program lives here public abstract class MyProjectNameWebTestBase : AbpWebApplicationFactoryIntegratedTest<Program> { protected virtual async Task<string> GetResponseAsStringAsync( string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) { var response = await Client.GetAsync(url); response.StatusCode.ShouldBe(expectedStatusCode); return await response.Content.ReadAsStringAsync(); } protected virtual async Task<T?> GetResponseAsObjectAsync<T>( string url, HttpStatusCode expectedStatusCode = HttpStatusCode.OK) { var str = await GetResponseAsStringAsync(url, expectedStatusCode); return JsonSerializer.Deserialize<T>(str, new JsonSerializerOptions(JsonSerializerDefaults.Web)); } } ``` A test then just requests a URL: ```csharp public class Index_Tests : MyProjectNameWebTestBase { [Fact] public async Task Welcome_Page() { var html = await GetResponseAsStringAsync("/"); html.ShouldContain("Welcome"); } } ``` ## The web test module The web-test startup module depends on `AbpAspNetCoreTestBaseModule` **and the SUT's `*WebModule`**, and does two load-bearing things in `PreConfigureServices`: register a `CompiledRazorAssemblyPart` for the Web assembly (without it the compiled Razor pages 404), and turn on the OpenIddict development certificate. ```csharp [DependsOn( typeof(AbpAspNetCoreTestBaseModule), typeof(MyProjectNameWebModule), typeof(MyProjectNameApplicationTestModule), typeof(MyProjectNameEntityFrameworkCoreTestModule) )] public class MyProjectNameWebTestModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) { context.Services.PreConfigure<IMvcBuilder>(b => b.PartManager.ApplicationParts.Add( new CompiledRazorAssemblyPart(typeof(MyProjectNameWebModule).Assembly))); context.Services.GetPreConfigureActions<OpenIddictServerBuilder>().Clear(); PreConfigure<AbpOpenIddictAspNetCoreOptions>(o => o.AddDevelopmentEncryptionAndSigningCertificate = true); } } ``` ## Faking a logged-in user There is **no built-in always-allow** for web tests, and the `FakeAuthentication` scheme + `FakeUserClaims` bag live in ABP's own test project — **not in any NuGet package**. Copy that pattern: register `AddAuthentication(...).AddFakeAuthentication()` in the test module, then per test resolve `FakeUserClaims` and push a claim before the request: ```csharp var fakeClaims = GetRequiredService<FakeUserClaims>(); fakeClaims.Claims.Add(new Claim(AbpClaimTypes.UserId, userId.ToString())); var page = await GetResponseAsStringAsync("/Identity/Users"); // now authenticated ``` With no claim pushed the request is anonymous, so a protected page returns `302` (remember `AllowAutoRedirect = false`). ## Validation - Hit `/` and assert `200` + expected markup. - Hit a protected page with no fake claim and assert `302`; push an `AbpClaimTypes.UserId` claim and assert `200`. ## Common Pitfalls - **Passing a module type as the generic argument.** It's `AbpWebApplicationFactoryIntegratedTest<Program>` — the SUT entry-point class, not the ABP module. - **Expecting `GetResponseAs*` from the package.** They aren't shipped; copy them into your `*WebTestBase`. - **Expecting a login page body on an unauthenticated request.** `Client` has `AllowAutoRedirect = false`, so you get a `302` — assert the status, not page content. - **Razor pages 404 in tests.** You skipped the `CompiledRazorAssemblyPart` registration for the Web assembly. - **Looking for a built-in fake login.** Copy the `FakeAuthentication` scheme + `FakeUserClaims` pattern; it isn't in a NuGet package.
View on GitHub