How to Write Architecture Tests for the Clean Architecture
Introduction to Software Architecture Testing
Overview of the Project Structure
- Milan introduces a project following clean architecture principles, highlighting its structure with a domain project at the center.
- The application layer references the domain project, while external projects (infrastructure and presentation) can reference both application and domain but not each other.
- A web project is mentioned that wires up dependency injection by referencing all previous projects.
Setting Up Architecture Tests
- Milan prepares an architecture test project and constants representing root namespaces for all solution projects.
- He installs a NuGet package called
netdarktest.rulesnecessary for writing architecture tests.
Writing the First Architecture Test
Domain Project Dependency Test
- The first test focuses on ensuring that the domain project does not depend on any other projects.
- An assembly variable is introduced to hold the domain project's assembly, using type operators to retrieve it.
- An array of strings is created containing namespaces of other projects to check against dependencies.
Asserting Dependencies
- Using methods from the installed library, Milan writes rules asserting that types in the domain assembly should not have dependencies on specified other projects.
- The test result is checked for success using fluent assertions, confirming that the initial test passes successfully.
Expanding Tests to Other Projects
Application Project Dependency Test
- Milan copies and modifies the existing test to focus on verifying that the application project does not reference certain other projects (infrastructure, presentation, web).
- Both tests are confirmed passing after running them again.
Infrastructure and Presentation Project Tests
- Similar tests are added for infrastructure and presentation projects, checking their respective dependencies against others in line with clean architecture principles.
Advanced Architecture Testing Techniques
Detailed Application Tests
- Milan discusses moving towards more detailed tests targeting specific aspects of the application assembly.
- He explains how commands and queries are structured within the CQRS pattern used in his application’s business logic.
This markdown file summarizes key points from Milan's discussion about software architecture testing while providing timestamps for easy navigation.
Creating Architecture Tests for Handlers and Controllers
Introduction to Dependency Testing
- The speaker introduces a new test focusing on ensuring that handlers have a dependency on the domain namespace, shifting from previous tests that checked for the absence of dependencies.
Writing the Test
- The test is named "handlers should have dependency" and involves editing the arrange-act-assert steps to set up the necessary conditions for testing. The application assembly is stored in a variable for use in this process.
Filtering Types in Assembly
- A condition is established to filter types within the application assembly, specifically targeting those whose names end with "handler." This follows a convention where all command and query handlers are expected to adhere to this naming structure.
Asserting Dependencies
- The test checks if types ending with "handler" have a dependency on the domain namespace, storing results in a variable and asserting that the test result's success property is true. Initial tests pass successfully, indicating correct implementation so far.
Validating Test Functionality
- To ensure the test functions correctly, an intentional error is introduced by removing references from a specific handler (get webinar by id). This leads to an expected failure of the test, confirming its effectiveness in detecting rule violations.
Example with Presentation Project
- Moving on to another example involving controllers, a new test checks if controllers depend on Mediator—a library used for sending commands and queries. The focus shifts back to writing tests from scratch while maintaining clarity about dependencies required by different components of the architecture.
Conclusion and Encouragement
- The speaker concludes by encouraging viewers to explore architecture tests further, suggesting they can easily implement such tests into their projects after reviewing relevant documentation. They invite feedback through likes and subscriptions as part of community engagement around these concepts.