A portfolio project demonstrating white-box testing of an ASP.NET Core REST API using NUnit, Moq, and EF Core in-memory SQLite. The emphasis is on test architecture, test readability, and multi-layer verification across unit and component tests.
| Project | Type | Description |
|---|---|---|
StudyGroupApi |
REST API | ASP.NET Core REST API — study group management (create, join, leave, search) |
StudyGroupApi.UnitTests |
Unit Tests | Domain logic + controller behavior via Moq |
StudyGroupApi.ComponentTests |
Component Tests | Controller + repository wired with SQLite in-memory DB |
The latest published HTML test report is available here:
- Detailed HTML report:
https://aliboztemir.github.io/csharp-whitebox-api-testing/details.html - Report landing page:
https://aliboztemir.github.io/csharp-whitebox-api-testing/
Because the report is published through GitHub Pages, it can be viewed by public/guest users without signing in, as long as the repository Pages site remains public.
This repository includes an automated CI/CD workflow using GitHub Actions.
On every push, pull request, or manual trigger:
- Checks out the repository
- Sets up .NET 8
- Restores NuGet dependencies
- Builds the solution in Release mode
- Runs all tests and generates TRX test results
- Publishes parsed test output to GitHub Checks
- Generates a customer-friendly HTML report and a detailed HTML report from TRX results
- Uploads TRX and HTML artifacts
- Deploys the HTML report to GitHub Pages when tests complete successfully
.github/workflows/tests.yml
You can manually run the workflow from the Actions tab using the Run workflow button.
After a successful run:
- GitHub Pages summary page is published as the landing page
- Detailed per-test HTML output is published at the detailed report link above
- Raw
.trxfiles remain available in workflow artifacts for technical traceability
This gives both a stakeholder-friendly report view and a developer-friendly raw execution record.
This project applies white-box testing principles across two test layers:
- Unit Tests — test individual classes in isolation, with dependencies replaced by Moq mocks. Includes domain entity validation and controller logic.
- Component Tests — test the controller and repository together using a real SQLite in-memory database. Exercises realistic dependency wiring, database persistence, and HTTP response behavior.
Located in StudyGroupApi.UnitTests/.
Tests StudyGroup entity construction and business rules directly:
- ID, name, subject, and date validation
- Boundary conditions (min/max name length, invalid enum values)
AddUser/RemoveUserbehavior including null and duplicate handling
Tests controller methods with a mocked IStudyGroupRepository:
- Verifies correct HTTP responses for all endpoints
- Verifies repository method invocation and invocation count using
Moq.Verify - Covers happy path and negative cases
Located in StudyGroupApi.ComponentTests/.
Tests the full controller → repository → SQLite pipeline:
- Realistic dependency wiring (no mocks)
- Verifies data is persisted to and read from the database
- Tests sorting, filtering, join, and leave behavior with real DB state
- Covers boundary and negative cases end-to-end
Located in shared file TestSupport/Builders/Builders.cs and linked by both test projects.
Builders provide sensible defaults and fluent configuration to reduce test setup duplication:
var user = new UserBuilder()
.WithId(1)
.WithName("Alice")
.Build();
var studyGroup = new StudyGroupBuilder()
.WithId(1)
.WithName("Math Club")
.WithSubject(Subject.Math)
.WithUser(user)
.Build();Controller unit tests use explicit Moq.Verify to confirm repository interactions:
_mockRepo.Verify(repo => repo.CreateStudyGroup(studyGroup), Times.Once);
_mockRepo.Verify(repo => repo.JoinStudyGroup(1, 1), Times.Once);
_mockRepo.Verify(repo => repo.CreateStudyGroup(It.IsAny<StudyGroup>()), Times.Never);This makes white-box intent explicit — not just what the controller returns, but how it interacts with its dependencies.
Tests are tagged with relevant categories for selective execution:
| Category | Meaning |
|---|---|
Unit |
Isolated unit test (mocks, no I/O) |
Component |
Wired test with real dependencies |
Domain |
Tests on entity logic |
Controller |
Tests on controller behavior |
Validation |
Boundary or input validation scenarios |
Negative |
Tests for rejection, error, or failure cases |
Run by category:
dotnet test --filter TestCategory=Unit
dotnet test --filter TestCategory=Negative
dotnet test --filter TestCategory=Component| Scenario | Unit Tests | Component Tests |
|---|---|---|
| Create Study Group | ✓ | ✓ |
| Validate Study Group Name | ✓ | ✓ |
| Validate Subject | ✓ | ✓ |
| Join Study Group | ✓ | ✓ |
| Leave Study Group | ✓ | ✓ |
| List Study Groups | ✓ | ✓ |
| Search by Subject | ✓ | ✓ |
| Repository Persistence | — | ✓ |
# All tests
dotnet test StudyGroupApi.sln
# Unit tests only
dotnet test StudyGroupApi.UnitTests/
# Component tests only
dotnet test StudyGroupApi.ComponentTests/- .NET 8 / ASP.NET Core Web API
- Entity Framework Core (SQLite / SQL Server)
- NUnit 3
- Moq
- GitHub Actions CI/CD