In this lesson, you will learn how to design targeted integration tests that verify your application’s authorization and input validation boundaries.
The Principle of Negative Testing
When testing security-sensitive logic, the goal is not just to verify that the "happy path" works, but to prove that your security policy is enforced even when an attacker (or a compromised user) tries to bypass it. You should treat your integration tests as a security boundary layer, ensuring that WebApplicationFactory correctly replicates your production authorization policies.
Testing Authorization Policies
For security-sensitive endpoints, it is insufficient to simply test that a user can see their own data. You must explicitly verify that a user cannot access another user's data or perform unauthorized administrative actions. Use Authentication hooks (learned in lesson 7) to mock distinct roles and identities.
[Fact]
public async Task GetUser_ShouldReturnForbidden_WhenAccessingOtherUserData()
{
// Arrange: Authenticate as 'StandardUser'
var client = _factory.CreateAuthenticatedClient(userId: "user-123");
// Act: Attempt to access 'user-456' data
var response = await client.GetAsync("/api/users/user-456/profile");
// Assert: Verify strict boundary enforcement
Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
}
Testing Input Validation Boundaries
Security-sensitive logic often fails due to improper input sanitization. Your tests should treat inputs as untrusted vectors. Instead of testing for functional correctness, create test cases that inject malicious payloads, such as excessively long strings or unexpected data formats, to ensure that your model validation ([Required], [Range], [MaxLength]) and custom validation logic trigger a 400 Bad Request before the data touches your business services.
Specialized Test Suites
To keep these secure, separate your security tests from general integration tests. Create a specific suite that runs these cases with a clean state, ensuring that if your Policy or Middleware configuration changes, your security suite acts as a regression gate. When testing sensitive logic, verify the side effects: if an authorization check fails, ensure that no database records were created or modified during the attempt.
Key Takeaway: Security-sensitive tests must prioritize "negative" scenarios, ensuring that authentication, authorization, and input validation act as immutable barriers that reject unauthorized access and malformed data before execution begins.