Skip to content

Commit b7735e6

Browse files
feat: add favorite tech stack
1 parent d0cbf01 commit b7735e6

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

docs/recommendations.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
# Recommendations
22

3-
## 1. Unit vs Integration Tests
3+
## What is your recommended tech stack for Java backend development?
4+
- **Language:** Java / Kotlin
5+
- **Frameworks:** Spring Boot, Quarkus
6+
- **Design & Architecture:** Modular Monolith, Package-by-Feature
7+
- **Database:** PostgreSQL, Flyway Migrations
8+
- **Testing:** Integration Tests with Testcontainers, Unit Tests with Mockito, API Stubbing with WireMock
9+
- **Architecture Tests:** Spring Modulith Tests, ArchUnit Tests with Taikai
10+
- **Library Upgrades:** Renovate, Dependabot, OpenRewrite
11+
- **IDE:** IntelliJ IDEA
12+
- **Build Tool:** Maven
13+
- **Code Formatting:** Spotless Plugin with Palantir Java Format
14+
15+
## Unit vs Integration Tests
416
I used to strictly follow the [Test Pyramid](https://martinfowler.com/articles/practical-test-pyramid.html) approach, but over time, I've realized that it's not always the most effective strategy. Many of the applications I've worked on have relatively simple business logic but rely heavily on integrations with external systems such as SQL databases, messaging systems, and third-party REST APIs. For such applications, unit tests often provide limited value. Instead, I recommend focusing on integration tests that validate how the application behaves when interacting with real external systems.
517

618
That said, it's not about choosing only unit tests or only integration tests. The most effective testing strategy involves a balanced mix of different types of tests to ensure comprehensive coverage and reliable behavior.
@@ -10,12 +22,12 @@ That said, it's not about choosing only unit tests or only integration tests. Th
1022
3. **Slice Tests:** While integration tests are valuable, it's not always necessary to spin up all dependencies for certain scenarios. For example, when testing invalid REST API payloads, you don't need a database or message broker. In such cases, slice tests are ideal — they load only a subset of components while mocking the rest. In Spring Boot, you can use annotations like `@WebMvcTest`, `@DataJpaTest`, and others to achieve this.
1123

1224

13-
## 2. Testcontainers tests are taking too much time. What should I do?
25+
## Testcontainers tests are taking too much time. What should I do?
1426
1. Use [Testcontainers Singleton approach](https://www.sivalabs.in/blog/run-spring-boot-testcontainers-tests-at-jet-speed/) to use the same containers for all tests.
1527
2. Use [Testcontainers reuse](https://java.testcontainers.org/features/reuse/) feature to keep the containers running in the background instead of stopping and restarting.
1628
3. If you are using Testcontainers with PostgreSQL, consider using [dbsandboxer](https://github.com/misirio/dbsandboxer) to speed up test execution by using PostgreSQL's template database feature.
1729

18-
## 3. Mockito vs In-Memory Implementation for Mocking
30+
## Mockito vs In-Memory Implementation for Mocking
1931
When writing unit tests for a service layer class(`CustomerService`), a common challenge is managing its dependencies, such as the `CustomerRepository`. We need a way to isolate the service logic from the actual data access implementation to ensure the test only validates the service's behavior. Two primary techniques for achieving this isolation are using a mocking framework like Mockito or creating an In-Memory implementation of the dependency.
2032

2133
Let's assume the following simplified interfaces and class structures:
@@ -246,14 +258,14 @@ For example, a test verifying a feature expects a search query to return 23 reco
246258

247259
So, I recommend using Mockito so that you control the exact conditions of the test without the maintenance overhead and brittleness associated with managing a secondary, in-memory dependency implementation.
248260

249-
## 4. Should I aim for 100% Test Coverage?
261+
## Should I aim for 100% Test Coverage?
250262
Striving for 100% test coverage often leads to a blind ritual rather than a genuine pursuit of quality. While the metric was intended to encourage thorough testing, obsessively chasing the final few percentage points frequently results in writing trivial, brittle tests that simply confirm getter/setter calls or other low-value code, without actually verifying meaningful system behavior.
251263

252264
The reality is that high test coverage doesn't necessarily mean high-quality code; a project can have 100% coverage yet still fail to test critical business logic or edge cases.
253265

254266
Instead of a rigid target, a more pragmatic approach is to aim for a solid foundation, such as 80% code coverage, prioritizing a good test suite focused on verifying system behavior, complex logic, and integration points, which provides the most value for maintaining a robust application.
255267

256-
## 5. How to enforce a common coding style in a team?
268+
## How to enforce a common coding style in a team?
257269
Code formatting and linting are frequently discussed — and sometimes hotly debated — topics within development teams. In reality, these discussions often consume more time than they should. Once a team agrees on a standard formatting approach, it typically becomes second nature within a week, and few developers think about it again.
258270

259271
To maintain consistency and avoid unnecessary debates, it’s best to adopt a well-established tool and automate formatting as part of your build or CI process. Some popular options include:

0 commit comments

Comments
 (0)