Chaturmind
LearnDSASystem DesignInterview PrepDevOpsEngineering GrowthBlog
Start learning
Chaturmind

Structured learning paths for engineers who want to go deep. Written by practitioners.

Learn

  • Java
  • DSA
  • System Design
  • Spring Boot
  • AI / ML
  • DevOps
  • Engineering Growth
  • Java Interview Prep

Company

  • Blog
  • Contact

Legal

  • Privacy Policy
  • Terms of Service

© 2026 Chaturmind. All rights reserved.

Built for engineers who want to go deep.


← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
Chaturmind
← Java Interview Prep: 8+ Years (Senior & Lead)

Expert Core Java

  • Tricky Java Output, Operators & OOP Edge Cases — Interview Questions
  • Tricky Exceptions, Memory & Keyword Questions — Interview Questions
  • Classic Java Language Questions, Senior-Grade Answers — Interview Questions
  • Classic Collections, Threads & JDK APIs, Senior-Grade Answers — Interview Questions
  • Reflection, Dynamic Proxies, final & Modern OOP Design — Interview Questions

JVM Internals & Performance

  • Class Loading, Bytecode & Object Layout — Interview Questions
  • JIT Compilation & Runtime Optimisations — Interview Questions
  • Garbage Collectors Deep Dive — Interview Questions
  • JVM Tuning, GC Logs & Memory Footprint — Interview Questions
  • Memory Leaks, OutOfMemoryErrors & Profiling Tools — Interview Questions
  • Modules, Agents & Advanced JVM APIs — Interview Questions

Collections & Concurrency at Scale

  • Collections Internals & Complexity — Interview Questions
  • Iterators, Comparators & Ordering Contracts — Interview Questions
  • Concurrent Collections, Queues & Lock-Free Structures — Interview Questions
  • Threads, Executors & ForkJoin Internals — Interview Questions
  • Locks, Atomics, CAS & Synchronizers — Interview Questions
  • Java Memory Model, volatile, Fences & ThreadLocal — Interview Questions
  • Deadlock, Livelock, Starvation & Concurrent Design — Interview Questions
  • CompletableFuture, Parallel Streams & Non-Blocking I/O — Interview Questions

Modern Java (8 to 21+)

  • Lambdas & Functional Interfaces Internals — Interview Questions
  • Streams & Collectors Deep Dive — Interview Questions
  • Optional & Interface Default/Static Methods — Interview Questions
  • Java 9–25 Features & Virtual Threads — Interview Questions

Design Patterns, SOLID & Clean Code

  • Design Pattern Trade-offs & Combinations — Interview Questions
  • SOLID, Clean Code & Anti-Patterns — Interview Questions

Spring & Spring Boot Internals

  • IoC, Dependency Injection & Bean Lifecycle Internals — Interview Questions
  • Spring AOP, Proxies & @Async Internals — Interview Questions
  • Spring Configuration, Auto-Configuration & Custom Starters — Interview Questions
  • Spring MVC & REST Internals, Exception Frameworks — Interview Questions
  • Spring Security Advanced Internals — Interview Questions
  • Spring WebFlux, Reactor & R2DBC — Interview Questions
  • Spring Cloud, Observability & Distributed Tracing — Interview Questions
  • Spring Boot 3, Native Images & Production Scenarios — Interview Questions

JPA, Hibernate & Databases at Scale

  • Spring Data JPA — Queries, Projections, Custom Repositories & Locking — Interview Questions
  • JPA Entity Mapping, Associations & Cascades — Interview Questions
  • JPQL vs Native Queries in Depth — Interview Questions
  • Hibernate Caching — First-Level, Second-Level & Query Cache — Interview Questions
  • Lazy vs Eager Loading, LazyInitializationException & N+1 — Interview Questions
  • JPA Transactions, Propagation, Isolation & Dirty Checking — Interview Questions
  • SQL vs NoSQL, Indexing & Query Tuning — Interview Questions
  • Database Scaling, Replication, Pooling & Consistency Models — Interview Questions
  • Redis, Search, Time-Series, CDC & Transactional Data Modelling — Interview Questions

Testing Strategy & API Design

  • Spring Boot Test Slices, Context & Test Strategy — Interview Questions
  • Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions
  • JUnit 5 & Mockito, Advanced — Interview Questions
HomeLearnJava Interview PrepJava Interview Prep: 8+ Years (Senior & Lead)Testing Strategy & API Design
✓ FreeAdvanced· 13 min read

Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions

MockMvc vs TestRestTemplate, testing exception handlers, form submissions, status/header/body assertions, authenticated endpoints, file upload/download and multipart mocks, content negotiation, jsonPath; @DataJpaTest database setup, loading data and @Sql, testing validation constraints, Testcontainers over H2, custom JPQL queries, lazy loading, schema mismatches, rollback vs persistence across tests, locking scenarios; JWT/OAuth2-protected endpoints, disabling security for tests, profile configs, @TestPropertySource, scheduled/async methods, parallel runs, embedded Kafka, and coverage tools.

Published September 25, 2026


How to use this lesson

These are "how exactly would you test X" questions. Give concrete code, and mention what the test doesn't cover. A good test proves one behaviour, with realistic infrastructure where the behaviour depends on it.

Q1. What's the difference between MockMvc and TestRestTemplate?

Short answer:

  • MockMvc: calls the DispatcherServlet in-process, with no real HTTP server (@WebMvcTest, or @SpringBootTest + @AutoConfigureMockMvc). It's fast, and gives rich assertions (status(), jsonPath(), model()), and it's on the same thread as the test, so @Transactional test rollback applies. It doesn't exercise the servlet container: Tomcat error pages, the actual HTTP connection, compression, and some filter-ordering subtleties.
  • TestRestTemplate (or WebTestClient/RestClient against RANDOM_PORT): makes real HTTP calls to an embedded server. It's the most realistic (serialisation over the wire, the container's behaviour, the whole filter chain). It's slower, and the server-side work runs on other threads (no test rollback).
  • MockMvcTester (Boot 3.4) adds AssertJ-style fluent assertions over MockMvc.

Q2. How do you test a controller advice or global exception handler?

Short answer: Use @WebMvcTest (the advice is included in the slice). Make the mocked service throw each exception type, then assert the status and error body:

@WebMvcTest(OrderController.class)
class ErrorHandlingTest {
    @Autowired MockMvc mvc;
    @MockitoBean OrderService service;

    @Test void notFoundMapsTo404ProblemDetail() throws Exception {
        given(service.get(ID)).willThrow(new OrderNotFoundException(ID));
        mvc.perform(get("/api/orders/{id}", ID))
           .andExpect(status().isNotFound())
           .andExpect(content().contentType(MediaType.APPLICATION_PROBLEM_JSON))
           .andExpect(jsonPath("$.errorCode").value("ORDER_NOT_FOUND"))
           .andExpect(jsonPath("$.detail").value(containsString(ID.toString())));
    }
    @Test void unexpectedErrorsDoNotLeakDetails() throws Exception {
        given(service.get(ID)).willThrow(new IllegalStateException("SQL: select * from secret_table"));
        mvc.perform(get("/api/orders/{id}", ID))
           .andExpect(status().isInternalServerError())
           .andExpect(jsonPath("$.detail").value("Unexpected error"));
    }
}

You can also unit-test the advice class directly, or use MockMvcBuilders.standaloneSetup(controller).setControllerAdvice(advice).

Q3. How do you test @ModelAttribute binding, or form submissions?

Short answer: Send form parameters with MockMvc, then assert the binding errors, the model or the redirect:

mvc.perform(post("/register").contentType(MediaType.APPLICATION_FORM_URLENCODED)
        .param("email", "not-an-email").param("name", "")
        .with(csrf()))                                                 // form posts need CSRF when security is on
   .andExpect(status().isOk())
   .andExpect(view().name("register"))
   .andExpect(model().attributeHasFieldErrors("form", "email", "name"));

mvc.perform(get("/orders").param("status", "PAID").param("page", "2"))  // query parameters to @ModelAttribute search DTOs
   .andExpect(status().isOk());

Q4. How do you assert the status, headers and body of an HTTP response? What does .andExpect(jsonPath(...)) do?

Short answer: Use MockMvc's ResultMatchers:

  • status().isCreated();
  • header().string("Location", endsWith("/orders/42"));
  • content().contentType(APPLICATION_JSON);
  • content().json("{...}", JsonCompareMode.LENIENT) (JSONassert);
  • jsonPath("$.lines.length()").value(3), jsonPath("$.items[?(@.sku=='A1')].qty").value(hasItem(2)), jsonPath("$.id").exists().

jsonPath evaluates a JsonPath expression against the JSON response body, and asserts on the result (with Hamcrest matchers, or .value(...)), so it checks structure and specific fields without matching the whole document. With TestRestTemplate, assert on the ResponseEntity's status, headers and body (with AssertJ, or JSONassert for the body).

Q5. How do you test endpoints that require authentication, including JWT and OAuth2?

Short answer:

  • Mock users: @WithMockUser(roles = "ADMIN"), @WithAnonymousUser, and @WithUserDetails("alice") (it loads a real UserDetailsService).
  • JWT resource servers: mvc.perform(get("/api/orders").with(jwt().jwt(j -> j.subject("u1").claim("scope", "orders.read")))). This bypasses the token decoding, but applies the authorities and claims.
  • OAuth2 login or clients: oauth2Login(), oidcLogin(), oauth2Client() post-processors.
  • Reactive: webTestClient.mutateWith(mockJwt()).
  • Negative tests: assert 401 without a token and 403 without the scope. Test object-level rules (another user's resource gives 403 or 404).
  • Full-stack tests: real tokens from Testcontainers Keycloak, or from a mock OAuth2 server.

Q6. How do you disable security only for tests?

Short answer: Prefer not to. Testing with security on catches real misconfigurations. If you must:

  • in @WebMvcTest, @AutoConfigureMockMvc(addFilters = false) skips the servlet filters (including security) for pure controller-logic tests;
  • a test SecurityFilterChain in a @TestConfiguration that permits all (make sure it's only active in tests);
  • @WithMockUser everywhere (keeps security on, and is cleaner).

Never add permitAll production configuration behind a "test" profile that could accidentally be activated.

Q7. How do you test file uploads and downloads? How do you mock multipart uploads?

Short answer:

MockMultipartFile file = new MockMultipartFile("file", "invoice.pdf", "application/pdf", pdfBytes);
MockMultipartFile meta = new MockMultipartFile("meta", "", "application/json", """{"orderId":"42"}""".getBytes());

mvc.perform(multipart("/api/documents").file(file).file(meta).with(jwt()))
   .andExpect(status().isCreated());

mvc.perform(get("/api/documents/{id}/content", DOC_ID).with(jwt()))
   .andExpect(status().isOk())
   .andExpect(header().string(HttpHeaders.CONTENT_DISPOSITION, containsString("invoice.pdf")))
   .andExpect(content().bytes(pdfBytes));

Also test:

  • size limits (the max-file-size violation gives 413, or a mapped error);
  • invalid content types;
  • streaming downloads (for StreamingResponseBody, use asyncDispatch).

With a real server, use TestRestTemplate with a MultiValueMap body and FileSystemResource/ByteArrayResource.

Q8. How do you test content negotiation (JSON and XML)?

Short answer: Send Accept headers, and assert the Content-Type and body format:

  • mvc.perform(get("/api/orders/1").accept(MediaType.APPLICATION_XML)), then content().contentType(APPLICATION_XML) and xpath("/order/id").string("1");
  • JSON gives jsonPath(...);
  • an unsupported Accept gives 406;
  • an unsupported request Content-Type gives 415.

Include the XML converter dependency (jackson-dataformat-xml) in the test classpath, if the application supports XML.

Q9. How does @DataJpaTest configure the database? How do you load data before tests? What is @Sql for?

Short answer:

  • Database:

    • by default, it replaces the DataSource with an embedded database, and Hibernate's ddl-auto is set to create-drop (unless migrations run, since Flyway and Liquibase run in the slice);
    • it's @Transactional, with rollback per test;
    • use @AutoConfigureTestDatabase(replace = Replace.NONE) plus a Testcontainers database (@ServiceConnection) to test on the real engine.
  • Loading data:

    • @Sql("/fixtures/orders.sql") runs SQL scripts before (or after) each test, at class or method level, with executionPhase, and @SqlConfig for transaction modes;
    • TestEntityManager.persistAndFlush(...), or repositories in @BeforeEach;
    • Flyway test migrations (src/test/resources/db/testdata);
    • data.sql (applied at startup, and global, so less targeted).

    Keep fixtures minimal and local to each test for readability.

Q10. How do you test constraints and validation annotations?

Short answer:

  • Unit-test the constraints with a Validator (fast, with no Spring):
Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
var violations = validator.validate(new CreateOrderRequest("", List.of()));
assertThat(violations).extracting(v -> v.getPropertyPath().toString()).containsExactlyInAnyOrder("customerId", "lines");
  • Custom ConstraintValidators: test them directly, including null handling, or inside ApplicationContextRunner when they have injected dependencies.
  • The web layer: @WebMvcTest sends invalid payloads, and asserts 400 with the field errors in the Problem Details.
  • Database constraints (unique, FK, check): a @DataJpaTest on the real database (Testcontainers) with flush(), to trigger the constraint and assert DataIntegrityViolationException.

Q11. Can you use Testcontainers instead of H2? Why?

Short answer: Yes, and you should, for most integration tests. Testcontainers runs the same database engine and version as production (Postgres, MySQL, Oracle XE, SQL Server) in Docker, so you test:

  • real SQL dialects, native queries, JSON and array types, locking and isolation behaviour;
  • constraints, sequences, triggers;
  • Flyway migrations exactly as they'll run in production.

H2 compatibility modes miss many of these, which gives false confidence. The costs are Docker availability, and startup time (mitigated by singleton or reusable containers and context caching).

Q12. How do you test repository methods that use custom JPQL?

Short answer: Use @DataJpaTest on the real database:

  1. Arrange the entities covering matching and non-matching cases, and edge cases (nulls, boundaries, several tenants).
  2. flush() and clear() the persistence context, so the query really hits the database.
  3. Call the method.
  4. Assert the results and their ordering.
  5. Optionally, assert the SQL count (datasource-proxy), to catch N+1 regressions.

Test pagination (Pageable), and startup validation (a broken JPQL string fails context loading, which the test catches).

Q13. How do you verify lazy-loading behaviour in tests?

Short answer:

  • Hibernate.isInitialized(entity.getLines()), or PersistenceUnitUtil.isLoaded(entity, "lines"): assert that it's false after a plain findById (lazy works), and true after a fetch-join or entity-graph method.
  • Query counting: assert that loading N orders with their lines executes exactly 1 or 2 statements (datasource-proxy SQLStatementCountValidator, or Hibernate statistics' getPrepareStatementCount()).
  • LazyInitializationException tests: load in one transaction, then access outside it, to prove that your service returns fully initialised DTOs.
  • Remember to clear() the persistence context before loading, or you'll get cached instances.

Q14. What happens if you test JPA against a mismatched schema?

Short answer: It depends on the configuration:

  • with ddl-auto=validate, context startup fails with SchemaManagementException (a missing column or table, or a wrong type). That's good: it fails fast;
  • with create-drop/update in tests, Hibernate generates a schema from the entities, which hides the mismatch with the real migrations, so tests pass, and production fails;
  • with none, errors appear at query time (SQLGrammarException: an unknown column).

The best practice: run the real Flyway or Liquibase migrations in tests (on Testcontainers), with ddl-auto=validate, so entity and schema drift is caught in CI.

Q15. How do you roll back, or keep, data across multiple test cases?

Short answer:

  • Isolation (the default and recommended option): each test rolls back its transaction (@Transactional tests), or cleans up (@Sql after, truncation), so tests don't depend on each other's data, and can run in any order or in parallel.
  • Shared read-only fixtures: load them once per class (@BeforeAll with @TestInstance(PER_CLASS) and a committed transaction, or @Sql at class level with BEFORE_TEST_CLASS, Spring 6.1+). Treat them as immutable.
  • Keeping data on purpose: @Commit or @Rollback(false) for a scenario spanning several steps. Better still, put multi-step flows in one test method, or use ordered tests (@TestMethodOrder) sparingly.

Q16. How do you test optimistic and pessimistic locking scenarios?

Short answer:

  • Optimistic:

    1. load the same entity into two separate transactions or EntityManagers (using TransactionTemplate, not the test's transaction);
    2. modify and commit the first;
    3. modify and commit the second;
    4. assert ObjectOptimisticLockingFailureException, and that version incremented once.

    Also test your retry logic, or the 409 mapping.

  • Pessimistic:

    1. in thread A, open a transaction with PESSIMISTIC_WRITE on a row, and hold it (a latch);
    2. in thread B, attempt the same lock with a short lock timeout (jakarta.persistence.lock.timeout), and assert PessimisticLockingFailureException/LockTimeoutException, or that B waits until A commits;
    3. use CountDownLatch/Awaitility to coordinate.

Use Testcontainers with the real database, because H2's locking differs.

Q17. How do you test application properties, or profile-specific configuration? What's @TestPropertySource for?

Short answer:

  • @ConfigurationProperties binding and validation: ApplicationContextRunner.withPropertyValues(...), then assert the bound values, or that startup fails on invalid values.
  • Profiles: @ActiveProfiles("prod") plus assertions on the resolved properties (Environment) or the beans. Check that the profile-specific files load the expected values.
  • @TestPropertySource: adds test-specific property sources (inline properties = "a=b", or locations = "classpath:test.properties") with high precedence over the application's files, for a test class. @SpringBootTest(properties = …) is the Boot equivalent. @DynamicPropertySource is for values computed at runtime.

Q18. How do you test scheduled tasks or async methods?

Short answer:

  • Separate the logic from the trigger: test the job's service method directly (unit or integration), which is fast and deterministic.
  • @Async methods: call them through the Spring bean (the proxy), then wait for the result: CompletableFuture.get(timeout), or Awaitility (await().atMost(5, SECONDS).until(() -> repo.count() == 1)). For deterministic unit tests, configure a synchronous executor (SyncTaskExecutor) in a test configuration.
  • @Scheduled wiring: use a short interval in tests, and assert with Awaitility. Or use ScheduledTaskHolder to assert that the task is registered with the expected cron. Disable scheduling in unrelated tests (a conditional @EnableScheduling through a property).
  • Time: inject a Clock, and use a fixed or mutable test clock. Never Thread.sleep for synchronisation.

Q19. How do you run tests in parallel in Spring Boot?

Short answer:

  • JUnit 5 in-JVM parallelism: junit-platform.properties:
junit.jupiter.execution.parallel.enabled=true
junit.jupiter.execution.parallel.mode.default=same_thread
junit.jupiter.execution.parallel.mode.classes.default=concurrent

Use @Execution(CONCURRENT)/@ResourceLock to control it. Spring's context cache is thread-safe, and parallel classes can share contexts.

  • Build-level forking: Maven Surefire or Failsafe forkCount=1C with reuseForks, Gradle maxParallelForks. Every fork has its own JVM and context cache, so assign isolated infrastructure per fork (Testcontainers per fork, or unique database schemas).
  • Keep the tests independent: unique data, random ports, and no shared mutable singletons.

Q20. How do you test Kafka listeners and producers?

Short answer:

  • @EmbeddedKafka (spring-kafka-test): an in-JVM broker, which is fast and needs no Docker. Point spring.kafka.bootstrap-servers at ${spring.embedded.kafka.brokers}. Produce a record, then assert the listener's side effect (the database row, or a mock invocation) with Awaitility, or consume from the output topic with KafkaTestUtils.getSingleRecord.
  • Testcontainers Kafka (KafkaContainer/ConfluentKafkaContainer, with @ServiceConnection) gives the real broker behaviour, and the Schema Registry through additional containers.
  • Test:
    • serialisation and the schema;
    • error handling: DLT routing after the retries (produce a poison message, then assert it lands on orders.DLT);
    • idempotency (produce duplicates);
    • transactions and exactly-once semantics, where you use them.
  • Unit-test the listener logic by calling the handler method directly.

Q21. Which tools generate code coverage reports?

Short answer:

  • JaCoCo is the standard for Java: a Java agent instruments classes at runtime. Maven (jacoco-maven-plugin: prepare-agent, report, check with minimum thresholds) or Gradle (jacoco plugin). It reports line, branch, instruction and complexity coverage, as HTML or XML.
  • Aggregation and quality gates: SonarQube/SonarCloud (consumes the JaCoCo XML, with coverage on new code and gates in pull requests), Codecov and Coveralls.
  • IntelliJ's coverage runner, for local work.
  • Mutation testing: PIT (pitest) measures test effectiveness: it mutates the code, and checks that the tests fail. That's a better signal than line coverage alone.

Key points to cover:

  • Coverage is a floor, not a goal. Enforce reasonable thresholds on new code, and review what's untested rather than chasing 100%.

Follow-up questions this topic invites — and their answers

Q: What is Awaitility, and why is it better than Thread.sleep? A: A library for polling conditions with timeouts (await().atMost(…).untilAsserted(…)). It waits only as long as needed, gives clear failure messages, and avoids flaky fixed sleeps.

Q: How do you test that a transaction rolls back on failure? A: Use an integration test without a test-managed transaction. Call the service with input that fails midway, then query in a new transaction and assert that none of the partial changes persisted.

Q: Should tests use the production application.yml? A: Mostly yes, so the tests exercise the real configuration, with minimal test overrides (@TestPropertySource, @ServiceConnection), not a completely separate test configuration that drifts from production.

Q: What's a good way to keep test data builders readable? A: Test data builders or object mothers (anOrder().withStatus(PAID).withLines(2).build()), with sensible defaults, so each test states only what matters to it.

Previous

Spring Boot Test Slices, Context & Test Strategy — Interview Questions

Next

JUnit 5 & Mockito, Advanced — Interview Questions

AI Tutor

Lesson: Testing Web, Persistence, Security, Async & Messaging in Spring Boot — Interview Questions

Quick actions

AI responses can be inaccurate. Verify critical information.