Stacks

Write Unit Tests for Untested Java Code with Atlas (2026)

Updated 7 min read

Writing unit tests for untested Java code starts with knowing the full public surface of the class, and Atlas enumerates that surface with the lsp tool's documentSymbol operation instead of skimming the file. Atlas then copies the repo's existing test conventions rather than inventing its own: the framework, the import style, and the naming convention already used under src/test/java. The new class is written with the write tool, placed in the mirrored package, and then executed. Atlas runs JUnit 5 via mvn test with its bash tool, because the run is the point: a test that was never executed is not a test.

How do I know which methods of a Java class need unit tests?

Enumerate them, do not skim. Atlas uses the lsp tool's documentSymbol operation to list a Java class's exported symbols, so no public method is missed. A class with 3 declared public methods, 2 package-private helpers, and an inherited method from an abstract base has a wider surface than a quick scroll suggests.

Coverage decisions collapse when the surface is guessed. Java classes inherit, overload, and expose more than the eye catches: two overloads of the same method name are two behaviors, and an @Override of a base class method is a third. documentSymbol enumerates the declarations, turning the class into a checklist of public methods rather than an impression of one. Atlas indexes code by AST declarations using tree-sitter, not blind line windows, so each method declaration in src/main/java is a real unit in the index rather than an arbitrary slice of a 400-line file.

How does Atlas match my project's existing JUnit import style?

Atlas greps an existing test file under src/test/java to copy the repo's framework, import style, and naming convention. One project imports org.junit.jupiter.api.Test from JUnit 5 and calls assertEquals directly. Another routes every case through a shared fixture base class. Both are valid Java, and only the one your repo already uses will survive review.

Generated tests get rejected on style before anyone reads the assertions. Copying conventions is therefore not politeness, it is the difference between a merged pull request and a rewrite. Look for what the existing suite does about setup: does it use @BeforeEach, a builder, or a static fixture. Look at the naming: shouldReturnEmptyWhenInputIsNull reads differently from testGetItems, and mixing the two in one Maven module is noise. The pom.xml settles the framework question, since Maven resolves the JUnit 5 dependency that every test class in the module must import against.

Where should a new Java test class live?

A new Java test class belongs in the mirrored package under src/test/java. Maven's standard layout pairs 2 trees, src/main/java and src/test/java, so a class in the com.example.billing package gets its test in the identical package path on the test side, which is what lets the test reach package-private helpers without reflection.

Package mirroring is a Java convention with a practical payoff. A test class in the same package as its subject can exercise package-private methods directly, which frequently removes the temptation to widen a method to public purely for testability. Atlas places the new class accordingly and writes it with the write tool, which shows the diff in the permission prompt before anything lands on disk. Read the generated assertions before approving, particularly the null and exception cases, because a generated test can encode current behavior rather than intended behavior, and a wrong test that passes is worse than no test at all.

Does Atlas actually run the Java tests it writes?

Yes, and the run is the point. Atlas executes JUnit 5 via mvn test through its bash tool. Output over 2000 lines or 50 KB is truncated and the full log is saved to a file you can read, which matters because Maven prints a surefire report and a stack trace for every failing case in a multi-module build.

A test that was never executed is not a test, it is a guess formatted like one. Running the suite immediately catches the classic generated-test failures: a mocked collaborator that is never injected, an import that Maven cannot resolve, an assertion comparing a String to an Integer. Compilation errors in src/test/java surface first and cascade, so read the saved Maven log from the top rather than the tail. Then iterate with the edit tool until the suite is green, adding one test method at a time so a break is always attributable to the method you just added.

How do I test a large Java class without losing track?

Keep progress in a todowrite list when the module is large. Seed the list from the documentSymbol enumeration, one pending entry per public method, so a Java class with 8 public methods produces 8 entries and a session that covers the happy path does not silently skip the exception branches.

Testing passes tend to stall at the interesting part. The constructor and the obvious getter get covered, then attention drifts, and the class ends up with coverage that looks respectable while every error branch remains unexercised. A todowrite list built from the enumerated symbols makes the remaining work visible and specific. Work through it method by method, running JUnit 5 via mvn test after each addition. When the suite is green, run Spotless so the new test class matches the project's formatting, and every Atlas tool call along the way is permission-gated against allow, ask, and deny rules before it runs.

Step by step

  1. 01Run atlas in a project with a pom.xml or build.gradle so the Java packages, classpath, and build configuration are in scope.
  2. 02Read the untested class in src/main/java, then use the lsp tool's documentSymbol operation to enumerate its exported symbols so no public method or overload is missed.
  3. 03Grep an existing test file under src/test/java to copy the repo's framework, import style, and naming convention, including whether it uses @BeforeEach or a shared fixture base class.
  4. 04Write the new test class with the write tool, which shows the diff in the permission prompt before anything lands on disk, placing it in the mirrored package so package-private helpers stay reachable.
  5. 05Run the suite with the bash tool by invoking JUnit 5 via mvn test; output over 2000 lines or 50 KB is truncated and the full log is saved to a file you can read.
  6. 06Read the saved Maven log from the top, since a compilation error in src/test/java cascades into everything after it, then iterate with the edit tool until the suite is green.
  7. 07Seed a todowrite list from the documentSymbol enumeration, one pending entry per public method, so the exception branches are not skipped.
  8. 08Run Spotless so the new test class matches the project's formatting before you open the pull request.

Frequently asked questions

how to add junit 5 tests to a java class with no tests
Have Atlas read the class, enumerate its public methods with the lsp tool's documentSymbol operation, grep an existing test under src/test/java for the import style, then write the class and run JUnit 5 via mvn test.
will an ai agent write java tests that match my project conventions
Atlas greps an existing test file to copy the repo's framework, import style, and naming convention rather than inventing its own, so the generated class looks like the ones already in src/test/java.
where should java unit tests be placed in a maven project
In the mirrored package under src/test/java. Maven's standard layout pairs it with src/main/java, and the matching package lets a test exercise package-private helpers directly.
how do i make sure no public method goes untested in java
Use the lsp tool's documentSymbol operation to enumerate the class's exported symbols, including overloads, then seed a todowrite list with one pending entry per public method.
maven surefire output too long to read
Atlas's bash tool truncates output over 2000 lines or 50 KB and saves the full log to a file you can read. Read it from the top, because a compilation error in src/test/java cascades.
can i review a generated java test before it is written to disk
Yes. The write tool shows the diff in the permission prompt before anything lands on disk, and every Atlas tool call is permission-gated against allow, ask, and deny rules before it runs.
how do i format a generated java test class
Run Spotless, which Maven resolves from your pom.xml. Formatting before the pull request keeps review focused on the assertions rather than on whitespace.

Try Atlas in your terminal

The terminal-native AI coding agent. Free core, single binary.

Install Atlas

Related guides

Write Unit Tests for Untested Code with Atlas in 2026

How to write unit tests for untested code with Atlas in 2026: the lsp tool enumerates exported symbols, grep copies repo conventions, and bash actually runs the suite.

Atlas for Java in 2026

Adopt Atlas, the terminal-native AI coding agent, for Java development in 2026. Enhance your workflow with intelligent code search, refactoring, and robust safety features for Maven and Gradle projects.

Diagnose a hanging or long-running command in Java with Atlas (2026)

Diagnose a hanging Maven or Java command in 2026 with Atlas: read the shell_metadata block, tell slow apart from blocked on stdin, and re-run non-interactively.

Locate Where a Behavior Is Implemented in Java with Atlas (2026)

Atlas pinpoints the Java class and method behind a behavior with codebase_search, grep through ripgrep, and the lsp tool's findReferences across your Maven modules.

Plan a Multi-File Change Before Editing in Java with Atlas (2026)

Plan a Java refactor with Atlas in 2026 before touching src/main/java: plan mode denies edits, the lsp tool maps the class hierarchy, and plan_exit gates the handoff.

Upgrade a Java Dependency and Fix Breakage with Atlas in 2026

In 2026, Java developers use Atlas to upgrade Maven dependencies and resolve compile and test failures. Learn how Atlas automates the process, from pom.xml updates to JUnit 5 fixes.

Run the Test Suite and Triage the Failures in Java with Atlas (2026)

Turn a wall of red Maven output into a ranked list of root causes. Atlas runs JUnit 5 via mvn test in 2026, saves the full log, and triages Java failures by cause.

Rename a Symbol Across the Repo in Java with Atlas (2026)

How to rename a Java class, method, or constant across a repo with Atlas in 2026: lsp findReferences for callsites, grep for strings, edit replaceAll, then mvn test.

Browse this resource hub