BankCoreSolution: The Bank App Built to Teach You How to Break It, Then Prove It Works
A cleanly separated .NET banking system that turns MSTest, NUnit, xUnit, and formal test documentation into one connected training ground.
- BankCoreSolution uses banking as a wrapper for teaching verification, not as a product demo with tests added later.
- Its real novelty is the way one domain action can be examined by validation, business rules, and documentation at the same time.
- Three test frameworks are not redundant here, because each one is used to stress a different kind of behavior.
- The formal test docs make evidence part of the system, so defects, traceability, and coverage stay connected.
This Bank Exists to Be Tested
BankCoreSolution is not trying to look like a real bank product. It is trying to behave like a controlled lab where banking actions become test cases, defects become teaching material, and evidence is treated as a first-class artifact.
That is why the repo is interesting. The domain is familiar enough to understand quickly, but the structure around it is what matters: clean boundaries, deliberate bugs, three test frameworks, and documentation that lives beside the code instead of behind it.
The result feels less like a CRUD tutorial and more like a proof-of-correctness machine. You can trace a withdrawal from UI to service logic to test coverage to a defect log.
The Real Product Is the Testing Workflow
The repo’s core idea is simple: correctness is not asserted once. It is observed from several angles. The validation layer checks input, the business layer enforces account rules, the audit layer records what happened, and the test stack probes each checkpoint differently.
| Layer | What it does | Why it matters |
|---|---|---|
| Validation | Checks fields, roles, and basic input shape | Stops bad requests before business logic has to reason about them |
| Business rules | Applies account limits, balances, and transfer rules | Defines what the system is allowed to do |
| Audit | Records events and outcomes | Creates a trail you can inspect after the fact |
| Test docs | Maps requirements, defects, and coverage | Turns verification into an accountable process |
That is a much stronger teaching model than a monolithic demo app. Instead of saying 'here is a bank,' it says 'here is how a system proves that a bank action is valid, correct, and traceable.'
Inside the Core: A Clean Boundary Around Business Rules
The architecture is intentionally restrained. BankCore.Core holds the models, interfaces, and services. BankCore.Data provides in-memory repositories. BankCore.App is a thin console shell that wires everything together with manual dependency injection.
// Simplified shape of the flow
var validation = new ValidationService();
var audit = new AuditService();
var repo = new InMemoryAccountRepository();
var accountService = new AccountService(validation, repo, audit);
var result = accountService.Withdraw(accountId, 200m);
That manual wiring matters. It keeps the domain logic easy to interrogate because the business service is not hiding behind a web framework, a persistence framework, or a dependency injection container that obscures the edges.
Why Three Test Frameworks Instead of One
This is not framework fan fiction. The split is pedagogical. MSTest, NUnit, and xUnit are used to show that the same codebase can support different testing habits and different kinds of assertions without collapsing into one generic style.
| Framework | Best fit in this repo | What it teaches |
|---|---|---|
| MSTest | Role checks and straightforward coverage | How to express reliable baseline verification |
| NUnit | Decision-table style behavior and reversals | How to organize branching logic and scenarios |
| xUnit | Theory-driven calculations and rules | How to keep data-driven tests concise |
That arrangement makes the test suite feel intentional. It also makes a subtle point: framework choice is not just syntax. It is a way of shaping how you think about the behavior under test.
The Hidden Curriculum in the Test Docs
The most unusual part of the repo may be the documentation folder. Risk registers, defect logs, traceability matrices, and coverage reports are not side quests here. They are part of the system’s verification story.
That changes the tone completely. Testing stops being a CI checkbox and starts looking like a discipline with evidence, lineage, and accountability.
It also makes the repository more useful for teaching. A learner can move from requirement to test case to defect to coverage artifact and see how the whole chain fits together.
A formal trail from requirement to evidence
When a defect is logged, it is not just a bug note. It becomes a hinge between the code, the tests, and the documentation. That is a stronger habit than simply checking whether the suite is green.
What the Intentional Bugs Teach
The explicit bug markers, including BUG-005, are the clearest sign that this repo is meant for investigation. A hidden defect would make the exercise feel like ordinary debugging. A labeled defect turns the codebase into a guided exercise in test design.
// BUG-005: Daily withdrawal limit is set to initial deposit
// This is intentional for the learning setup and should be caught by tests.
That kind of comment does two things at once. It makes the failure legible, and it forces the reader to think about how a test should expose it. The lesson is not just that bugs exist. The lesson is that a good test suite should tell you where the model of the system breaks.
Why This Pattern Scales Better Than a Typical Demo App
A conventional tutorial app usually optimizes for speed of understanding. BankCoreSolution optimizes for depth of verification. That makes it a better training ground for developers who need to reason about systems, not just features.
| Dimension | Typical demo backend | BankCoreSolution |
|---|---|---|
| Domain logic | Present, but mostly illustrative | Isolated and easy to interrogate |
| Test strategy | Often one framework, one style | Three frameworks with distinct roles |
| Documentation | Lightweight or absent | Traceability, defects, and coverage are explicit |
| Fault discovery | Usually accidental | Deliberate and teachable |
| Educational value | Shows how to build | Shows how to prove it works |
That is the real differentiator. The repo trains a habit of thinking in systems. Behavior is not just implemented. It is validated, documented, and made inspectable.





