- feature-based folder
- formatter: eclipse-java-google-style
- checkstyle: IDE + google_checkstyle
- linting: sonarlint
- coverage: run
mvn jacoco:prepare-agent test install jacoco:report
- dockerized mysql for tests
- dev/prod separation deployments
- business logic in services only
- explicit mapping dto:entity (mapstruct yields unreachable code)
- validation
- controller-based exception handling
- ci + coverage stickers
Code:
- Only services are imported into
RestControllers
. No logic, validation or repositories involved. - Do not write validations by hand. Use
spring-boot-starter-validation
instead - Only
Validate
DTO's. This saves network resources if data not in proper format - Request/Response returned should only be DTO's (avoid 1:1 mapping of db entities and json)
Use explicit custom/generic mapping for request/response.
The goal is to avoid sending very large models and reduce API calls - Avoid
@Autowired
and use@RequiredArgsConstructor
andprivate final
This provides more room for unit testing. - Take note when
@Data
or@ToString
on@Entity
with any relationship like@OneToMany
Make sure to include@ToString.Exclude
on that specific field to fix conflicts - Create a
lombig.config
file on the root directory with contents
config.stopBubbling = true
andlombok.addLombokGeneratedAnnotation = true
to include@lombok.Generated
annotations for test coverage in jacoco Services
should contain all business logicDTO/Entity
conversions should happen inServices
Repositories
should contain all predefined/custom DB logic- Unless you find a way to progmatically run
checkstyles
andsonarlint
,
make sure push code with no warnings from ide lints. - Use
@ControllerAdvice
for Global Exception handler i.e. malformed requests, invalid path etc etc
otherwise use@ExceptionHandlers
per feature controller - Use easy-random for fast creation of pojo's in tests
Tests:
- Only use
@Mock
on unit-tested components - Unit tests should not use Spring: no
SpringBootTest
,MockBean
andAutowired
- All classes should only use
@RequiredArgsConstructor
andprivate final
fields - Use
@ExtendWith(MockitoExtension.class)
to enable@Mock
annotation. - Use
InjectMocks
for components requiring mocked Validations and logic
for incoming requests should be examined atunit-tests
- Mid unit-integration-test types should
@Mock
all external dependencies - Only test atleast one success/failure case for incoming requests on
Controllers
. Controllers
:MockMvc
for unit-tests,WebTestClient
for integration-test- Check serialization for each json response type of
Controllers
Mocks
only for unit-tests (e.g. services, logic, validations)Test slices
for mid unit-integration-tests (e.g. controllers, jpa)SpringBootTest
for integration-tests (e.g. testcontainers, external services)- Integration Tests should reflect overall behaviour of grouped components
Repositories
are only tested on integration-tests since JPA does the heavy lifting.
Testcontainers are more suited to reflect the production database, hence integration-test.- End-to-end tests should represent pre-production environment
- Always prefer to use
JUnit5
.@Test
annotation should point toorg.junit.jupiter.api.Test
- Use
mvn clean install > log-file.log
in CI/CD
Putting all logs into a logfile is necessary to avoid VM crashes. - Use IDE test runs when developing locally
- It talks to the database
- It communicates across the network
- It touches the file system
- It can’t run at the same time as any of your other unit tests
- You have to do special things to your environment (such as editing config files) to run it
GET /users/{username}
GET /users
POST /users
PUT /users
DELETE /users/{username}
id
username
bio
- put
"coverage-gutters.coverageReportFileName": "target/site/jacoco/index.html"
invscode settings.json
when developing in Java to enable coverage gutters
- exclude id fields from hashcode/equals
- exclude association fields which are not managed in given entity from hashcode/equals
- exclude all lazy loaded fields from toString method
- exclude fields possibly causing circular references from toString method
- Testing:
- Architecture:
- Exceptions:
- Validations:
- Security:
- Limit Exposed Fields: