Skip to content

feature: Add JUnit 5 unit test suite, JaCoCo coverage, and CI - #53

Open
devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1784072349-junit-jacoco-ci
Open

devin-ai-integration[bot] wants to merge 1 commit into
masterfrom
devin/1784072349-junit-jacoco-ci

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jul 14, 2026 •

Copy link
Copy Markdown

Summary

This repo previously had no automated tests and no CI. This PR establishes a complete unit-testing foundation for the Spring Boot / Java 8 app using the standard stack (JUnit 5 + Gradle) with JaCoCo coverage and a GitHub Actions workflow.

Three things happen here:

  1. Fix the broken Gradle build — build.gradle only declared spring-boot-starter-web, so ./gradlew build failed to compile (Application.java uses JdbcTemplate). Added the JDBC + H2 dependencies (already present in pom.xml) so the Gradle build actually compiles.
  2. Add test tooling — JUnit 5 (junit-jupiter) wired via test { useJUnitPlatform() }, plus the JaCoCo plugin for reporting and a jacocoTestCoverageVerification gate at 60% line coverage (check depends on it).
  3. Add 46 deterministic unit tests for the pure-logic components, and a CI workflow that runs them and reports coverage.
// build.gradle (key additions)
apply plugin: 'jacoco'
dependencies {
    compile("org.springframework.boot:spring-boot-starter-jdbc")   // was missing -> build failed
    compile("com.h2database:h2")
    runtime("org.springframework.boot:spring-boot-properties-migrator")
    testImplementation("org.junit.jupiter:junit-jupiter-api:5.2.0")
    testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.2.0")
}
test { useJUnitPlatform(); finalizedBy jacocoTestReport }
jacocoTestCoverageVerification { /* BUNDLE LINE COVEREDRATIO >= 0.60 */ }

Coverage: before → after

Measured with ./gradlew test jacocoTestReport (JaCoCo LINE counter).

Scope Before After
Overall project 0.00% (0/231 lines) 83.12% (192/231 lines)
Core modules (excludes hello.Application bootstrap) 0.00% (0/200) 96.00% (192/200)

Per-class line coverage after:

Class Lines Covered
hello.service.TopicService 79 71 (90%)
hello.controller.HelloController 29 29 (100%)
hello.controller.TopicController 11 11 (100%)
hello.controller.GreetingController 4 4 (100%)
hello.model.Topic 16 16 (100%)
hello.model.Customer 15 15 (100%)
hello.model.SimpleTimeClient 17 17 (100%)
hello.model.Quote / Value / Greeting 24 24 (100%)
hello.declaration.TimeClient 5 5 (100%)
hello.Application (main + external HTTP + JDBC bootstrap) 31 0 (excluded from scope)

The 8 uncovered lines in TopicService are catch (IOException) fallback branches in the NIO file methods and the Optional.get() unhappy path. Application is the executable bootstrap (main, RestTemplate calls to an external quotes API, live JdbcTemplate DDL) — not pure logic, so it is intentionally out of scope for unit testing.

Test strategy

  • Prioritized TopicService as requested — every pure-logic method is covered: makeDistinctAndSortCharacters, splitAllIdWithColonSelectIDWithJavaKeywordThenSortThenJoin, findIdHavingCharacter, the CRUD list ops, filtering/sorting, and the NIO file methods (findAllFilesInPathAndSort, find*, readFileWithStreamFunction).
  • Deterministic & fast — no network, no live services, no Spring context. Plain constructors; controllers with @Autowired fields get a real TopicService injected via reflection. File-based methods assert against the checked-in temp.txt / repo tree, so results are stable in CI.
  • Models & interfaces — POJO getters/setters/toString, SimpleTimeClient date/time mutation logic, and TimeClient static + default methods (getZoneId valid/invalid fallback, getZonedDateTime).
  • Coverage gate — jacocoTestCoverageVerification fails the build below 60% line coverage so coverage can't silently regress.

CI

New workflow .github/workflows/ci.yml runs on pushes/PRs to master: sets up JDK 8 (required by the Gradle 4.6 wrapper), caches Gradle, runs ./gradlew clean test jacocoTestReport jacocoTestCoverageVerification, writes a coverage table to the job summary, and uploads the test + JaCoCo reports as artifacts.

Verification

$ ./gradlew clean test jacocoTestReport jacocoTestCoverageVerification
BUILD SUCCESSFUL
46 tests completed, 0 failed

Link to Devin session: https://app.devin.ai/sessions/ab4482467b964de7aa27a84660d6758c
Requested by: @matthewguerra-cog


Devin Review

Status Commit
⚪ Not started —

Run Devin Review

Open in Devin Review (Staging)

- Fix Gradle build (add jdbc + h2 deps missing from build.gradle)
- Configure JUnit 5 (junit-jupiter) test task and JaCoCo reporting/verification (>=60% line coverage)
- Add 46 deterministic unit tests for TopicService and other pure-logic components (models, TimeClient, controllers)
- Add GitHub Actions CI workflow that runs tests and reports coverage
@devin-ai-integration

Copy link
Copy Markdown
Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant