-
Notifications
You must be signed in to change notification settings - Fork 11
Module 3: Comprehensive Testing Expansion - Unit, Integration, and Property-Based Tests #10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: frye <[email protected]>
Co-authored-by: frye <[email protected]>
Co-authored-by: frye <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements comprehensive testing expansion for the .NET Users Demo API, establishing robust testing practices across unit testing, integration testing, and property-based testing. The implementation provides extensive coverage with 33 tests (12 unit tests, 14 integration tests, and 7 property-based tests) while also completing the missing DeleteUser endpoint functionality.
- Creates complete xUnit test project infrastructure with proper dependencies
- Implements comprehensive unit tests for all CRUD operations with mocking
- Adds end-to-end integration tests using WebApplicationFactory
- Introduces property-based testing with FsCheck for edge case discovery
- Completes the previously unimplemented DeleteUser endpoint
Reviewed Changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| net-users-demo.sln | Adds test project reference with additional platform configurations |
| net-users-api/Program.cs | Exposes Program class for integration testing |
| net-users-api/Controllers/UsersController.cs | Implements DeleteUser endpoint functionality |
| net-users-api.Tests/net-users-api.Tests.csproj | Test project configuration with required dependencies |
| net-users-api.Tests/Controllers/UsersControllerTests.cs | Comprehensive unit tests for all controller methods |
| net-users-api.Tests/IntegrationTests/CustomWebApplicationFactory.cs | Test server factory for integration tests |
| net-users-api.Tests/IntegrationTests/UsersApiIntegrationTests.cs | End-to-end HTTP integration tests |
| net-users-api.Tests/PropertyTests/UserProfilePropertyTests.cs | Property-based tests with FsCheck |
| Debug|x64 = Debug|x64 | ||
| Debug|x86 = Debug|x86 | ||
| Release|Any CPU = Release|Any CPU | ||
| Release|x64 = Release|x64 | ||
| Release|x86 = Release|x86 | ||
| EndGlobalSection | ||
| GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x64.ActiveCfg = Debug|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x64.Build.0 = Debug|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x86.ActiveCfg = Debug|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|x86.Build.0 = Debug|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x64.ActiveCfg = Release|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x64.Build.0 = Release|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x86.ActiveCfg = Release|Any CPU | ||
| {F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|x86.Build.0 = Release|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|x64.ActiveCfg = Debug|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|x64.Build.0 = Debug|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|x86.ActiveCfg = Debug|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|x86.Build.0 = Debug|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|Any CPU.Build.0 = Release|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|x64.ActiveCfg = Release|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|x64.Build.0 = Release|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|x86.ActiveCfg = Release|Any CPU | ||
| {A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|x86.Build.0 = Release|Any CPU |
Copilot
AI
Oct 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Adding x64 and x86 platform configurations is unnecessary for a .NET 9 API project that typically targets Any CPU. These additional configurations add complexity without providing value for this type of project.
See below for a potential fix:
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2C0F837-02EA-42E5-BDC0-48C31DD4245D}.Release|Any CPU.Build.0 = Release|Any CPU
{A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A2C0E5CB-3069-4064-BF5D-06FB7D75C4E0}.Release|Any CPU.Build.0 = Release|Any CPU
| var controller = new UsersController(_mockLogger.Object); | ||
|
|
||
| // Act | ||
| var result = controller.CreateUser(null!); |
Copilot
AI
Oct 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Using the null-forgiving operator (!) to pass null to a method that expects non-null input is misleading in tests. Consider using a more explicit approach like casting (UserProfile?)null to make the intent clearer.
| var result = controller.CreateUser(null!); | |
| var result = controller.CreateUser((UserProfile?)null); |
| var existingId = "1"; | ||
|
|
||
| // Act | ||
| var result = controller.UpdateUser(existingId, null!); |
Copilot
AI
Oct 1, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[nitpick] Using the null-forgiving operator (!) to pass null to a method that expects non-null input is misleading in tests. Consider using a more explicit approach like casting (UserProfile?)null to make the intent clearer.
| var result = controller.UpdateUser(existingId, null!); | |
| var result = controller.UpdateUser(existingId, (UserProfile?)null); |
Overview
This PR implements comprehensive testing expansion for the .NET Users Demo API, establishing robust testing practices across three key areas: unit testing, integration testing, and property-based testing. The implementation ensures code quality, catches regressions early, and validates both happy paths and error scenarios.
Changes Made
1. Test Project Infrastructure
Created a complete xUnit test project at the solution level (
net-users-api.Tests) with the following structure:Dependencies installed:
2. Unit Tests (12 tests)
Implemented comprehensive unit tests for
UsersControllercovering all CRUD operations:All unit tests:
ILogger<UsersController>3. Integration Tests (14 tests)
Created end-to-end integration tests using
WebApplicationFactory<Program>that exercise the full HTTP request/response cycle:Integration tests validate:
4. Property-Based Tests (7 tests × 100 iterations = 700 test cases)
Implemented property-based tests using FsCheck to verify invariants with randomly generated inputs:
Each property test runs 100 iterations with different random inputs, providing extensive coverage and edge case discovery.
5. API Implementation Fixes
UsersController.cs: Implemented the
DeleteUser()endpoint which was previously throwingNotImplementedException:Program.cs: Added
public partial class Program { }to make the Program class accessible for integration testing with WebApplicationFactory.Test Results
✅ All 33 tests passing
Benefits
Testing Approach
All tests follow these principles:
Fixes #[issue-number]
Original prompt
This section details on the original issue you should resolve
<issue_title>Module 3: Testing Expansion</issue_title>
<issue_description># Module 3: Testing Expansion
Overview
This issue tracks the implementation of comprehensive testing expansion for the .NET Users Demo API. The goal is to establish robust testing practices across three key areas:
These testing initiatives will ensure code quality, catch regressions early, and validate both happy paths and error scenarios.
🤖 Instructions for GitHub Copilot Coding Agent
Please check off tasks in this list as you complete them during development. Keep the task list current to track progress.
When working on this issue:
[ ]to[x]as you complete each taskTask Checklist
Exercise 3.1: Comprehensive Unit Test Suite
Core Requirements:
net-users-api.TestsUsersControllerTestsclass with proper namespaceGetUsers() Tests:
GetUsers()- happy path (returns all users)GetUsers()- edge case (empty list)GetUser(id) Tests:
GetUser(id)- happy path (valid ID returns user)GetUser(id)- error case (invalid ID returns NotFound)GetUser(id)- edge case (null/empty ID)CreateUser() Tests:
CreateUser()- happy path (creates and returns 201)CreateUser()- error case (duplicate ID returns conflict)CreateUser()- validation (null/invalid data returns BadRequest)UpdateUser(id) Tests:
UpdateUser(id)- happy path (updates existing user)UpdateUser(id)- error case (non-existent user returns NotFound)UpdateUser(id)- validation (invalid data)DeleteUser(id) Tests:
DeleteUser(id)- happy path (deletes and returns NoContent)DeleteUser(id)- error case (non-existent user returns NotFound)Test Quality:
dotnet testand confirm all tests passStretch Goals:
Exercise 3.2: Integration Testing
Setup:
IntegrationTestsfolder in test projectMicrosoft.AspNetCore.Mvc.TestingpackageCustomWebApplicationFactory<Program>classUsersApiIntegrationTestsclassIntegration Tests:
Test Quality:
Stretch Goals:
Exercise 3.3: Property-Based Testing
Setup:
PropertyTestsfolder in test projectUserProfilePropertyTestsclassProperty Tests:
Test Quality:
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.