backend
FreeBackend Java — Spring Boot controllers/services, JUnit controller tests, MakeMe. Read this first for any backend work. Use when working on the Java Spring backend.
The English summary is being prepared. Showing the original description.
Backend Java tests, controller-level stable-boundary tests, JUnit, @Nested, MakeMe builders, @Transactional, parameterized tests. Use when writing or changing backend JUnit tests.
The English summary is being prepared. Showing the original description.
Run score Not tested
See how to installReview the instructions the agent will receive before you install.
Style ("small test" practice — stable boundary, data over mocks, focused assertions, concise makeMe): the unit-testing skill — follow that first.
Run backend verification from the repo root:
CURSOR_DEV=true nix develop -c pnpm backend:verify
When no database migration is involved, this is faster:
CURSOR_DEV=true nix develop -c pnpm backend:test_only
Always run all backend unit tests instead of a selected file or test case.
For dough-test-optimization, use backend:test_only as both the ordinary
feedback measurement and profiling run. Per-test timings are the time
attributes in backend/build/test-results/test/TEST-*.xml; keep any derived raw
profile outside committed files. To count Spring context boots, temporarily add
logging.level.org.springframework.test.context.cache=DEBUG to
backend/src/test/resources/application.properties (a logback-test.xml
logger is overridden by the test profile's logging.level.root=OFF); each rise
in the logged missCount is one boot. Revert it afterwards.
Backend application of the "small test" style (unit-testing skill):
makeMe preconditions and the real DB.Controller-style example:
@Test
void shouldBeAbleToSaveNoteWhenValid() throws UnexpectedNoAccessRightException {
Note note = makeMe.aNote().creatorAndOwner(userModel).please();
final NoteRealm noteRealm = controller.show(note);
assertThat(noteRealm.getId(), equalTo(note.getId()));
}
Prefer injecting the controller on ControllerTestBase (as above). Every Spring test of the test profile extends SpringTestBase (testability package), directly or through ControllerTestBase, so the suite shares one application context. Do not add @AutoConfigureMockMvc or extra @MockitoBean / @TestBean on a subclass unless that exact annotation mix already exists — each unique mix caches another ApplicationContext and Hikari pool; CI MySQL then fails with Too many connections while a local run still passes. To observe a package-private persistence table, query through EntityManager rather than opening a new MockMvc context.
Calling a controller method directly skips request binding. When a multipart or form DTO field name matters (for example a boolean the frontend sends by name), prove it with a request through an @Autowired MockMvc (multipart(...) with the real field name); SpringTestBase already configures MockMvc, so this adds no context.
Independent algorithm example:
@ParameterizedTest
@CsvSource({
"moon, partner of earth, partner of earth",
"Sedition, word sedition means this, word [...] means this"
})
void clozeDescription(String title, String markdown, String expectedClozeDescription) {
assertThat(
new ClozedString(clozeReplacement, markdown).hide(new NoteTitle(title)).maskedContentAsMarkdown(),
containsString(expectedClozeDescription));
}
SpringTestBase rolls back after each test.@Formula field (for example Note.trashedInDatabase) is hydrated only when Hibernate loads the row from the database. An entity persisted or moved earlier in the same persistence context still carries the Java default, so a test that reads such a field through a loaded collection must makeMe.refresh(entity) first. Query-level predicates (Note.JPA_AVAILABLE) evaluate in SQL and need no refresh.SPRING_SESSION row in Spring Session's own transaction, outside that rollback. Such a test class is non-transactional and deletes its session rows after each test (see DevelopmentAuthenticationConfigurationTest). Session cookie attributes apply only on the embedded server, so a test asserting them uses webEnvironment = RANDOM_PORT.Example (TextContentValidatorTest): no restated Spring annotations; makeMe comes from the base.
class TextContentValidatorTest extends SpringTestBase {
@Autowired Validator validator;
@Test
void defaultNoteIsValid() {
assertThat(validator.validate(makeMe.aNote().inMemoryPlease()), is(empty()));
}
}
makeMe factory; chain methods; end with please() (or please(boolean) for persistence control).unit-testing skill for when to extend them vs set fields in the test.notebookOwnedBy(user) so aMemoryTrackerFor(note) inherits the owner.Note note = makeMe.aNote()
.notebookOwnedBy(user)
.title("title")
.content("description")
.please();
@Nested.@BeforeEach for common setup, keeping setup minimal and relevant to the group.unit-testing skill. Backend exception: external services only — mock OpenAIClient structured Responses output with OpenAiStructuredResponseMock in controller tests.assertThat with descriptive matchers; assertThrows for exceptions; @ParameterizedTest when inputs vary but the assertion focus stays the same.unit-testing skill.No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Backend Java — Spring Boot controllers/services, JUnit controller tests, MakeMe. Read this first for any backend work. Use when working on the Java Spring backend.
The English summary is being prepared. Showing the original description.
Backend Java production code, Spring Boot controllers/services/repositories, controller return values, imports, schema ERD pointer. Use when editing backend production Java.
The English summary is being prepared. Showing the original description.
related to donut CLI. Use when working on donut-cli.
The English summary is being prepared. Showing the original description.
Set up and run the Donut dev environment on Cursor Cloud VM (no Nix). Use when working on Cloud VM, running tests on Cloud VM, or encountering command errors related to missing nix. Triggers on: cloud VM, cloud agent, no nix available, /workspace path.
The English summary is being prepared. Showing the original description.
Regenerate docs/database-erd.md from MySQL information_schema (Mermaid ERD: foreign keys and key columns). Use after Flyway schema changes, new migrations, or when the diagram is stale. Triggers on: database ERD, database-erd.md, export_database_erd, schema diagram, ER diagram after migration.
The English summary is being prepared. Showing the original description.
Database migration, Flyway, SQL migrations, schema changes, database versioning, migration files, squashing historical migrations. Use when adding or changing Flyway migrations or schema.
The English summary is being prepared. Showing the original description.