spring-test-slices: Spring Boot 4.1.2 test slices lab (@WebMvcTest, @JsonTest, @RestClientTest, @DataJpaTest vs @SpringBootTest)

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_017ic4b7Jbw5CxUQ13D7gn25
This commit is contained in:
Claude
2026-11-14 15:26:55 +05:30
parent c92977b23d
commit d7497c8ab1
53 changed files with 1547 additions and 0 deletions
@@ -0,0 +1,19 @@
@WebMvcTest(BookController.class) with @MockitoBean BookService
GET /api/books/1 -> 200 {"isbn":"9780134685991","title":"Effective Java","author":"Joshua Bloch","price":"INR 499.00","published_on":"2018-01-06"}
GET /api/books/99 -> 404 {"detail":"No book with id 99","instance":"/api/books/99","status":404,"title":"Book not found"}
beans in this context:
BookController (@RestController)=yes
ApiExceptionHandler (@ControllerAdvice)=yes
PriceJson (@JacksonComponent)=yes
MockMvc=yes
JsonMapper (Jackson 3)=yes
BookService (@Service)=yes
BookRepository (Spring Data)=no
EntityManagerFactory=no
DataSource=no
RestClient.Builder=no
IsbnLookupClient (@Component)=no
AuditLogger (@Component)=no
bean definitions=126
@@ -0,0 +1,19 @@
@JsonTest with JacksonTester<BookView>
write(view) -> {"isbn":"9780134685991","title":"Effective Java","author":"Joshua Bloch","price":"INR 499.00","published_on":"2018-01-06"}
parseObject(...).price() -> Price[currency=INR, amount=499.00]
beans in this context:
BookController (@RestController)=no
ApiExceptionHandler (@ControllerAdvice)=no
PriceJson (@JacksonComponent)=yes
MockMvc=no
JsonMapper (Jackson 3)=yes
BookService (@Service)=no
BookRepository (Spring Data)=no
EntityManagerFactory=no
DataSource=no
RestClient.Builder=no
IsbnLookupClient (@Component)=no
AuditLogger (@Component)=no
bean definitions=35
@@ -0,0 +1,19 @@
@RestClientTest(IsbnLookupClient.class), base URL from application.properties
lookup(9780134685991) -> Optional[IsbnInfo[isbn=9780134685991, title=Effective Java, author=Joshua Bloch, pages=412]]
lookup(0000000000) -> Optional.empty
beans in this context:
BookController (@RestController)=no
ApiExceptionHandler (@ControllerAdvice)=no
PriceJson (@JacksonComponent)=yes
MockMvc=no
JsonMapper (Jackson 3)=yes
BookService (@Service)=no
BookRepository (Spring Data)=no
EntityManagerFactory=no
DataSource=no
RestClient.Builder=yes
IsbnLookupClient (@Component)=yes
AuditLogger (@Component)=no
bean definitions=53
@@ -0,0 +1,20 @@
@DataJpaTest
findByAuthorIgnoreCaseOrderByTitle("ANN") -> [Apple, Zebra]
DataSource class -> EmbeddedDataSourceProxy
JDBC URL starts with jdbc:h2:mem: -> true
beans in this context:
BookController (@RestController)=no
ApiExceptionHandler (@ControllerAdvice)=no
PriceJson (@JacksonComponent)=no
MockMvc=no
JsonMapper (Jackson 3)=no
BookService (@Service)=no
BookRepository (Spring Data)=yes
EntityManagerFactory=yes
DataSource=yes
RestClient.Builder=no
IsbnLookupClient (@Component)=no
AuditLogger (@Component)=no
bean definitions=80
@@ -0,0 +1,3 @@
b_firstTestInsertsOneRow -> count after save = 1
c_secondTestStillSeesOnlyItsOwnRow -> count after save = 1
(the row from b_ was rolled back when its test ended)
@@ -0,0 +1,19 @@
@SpringBootTest + @AutoConfigureMockMvc, @MockitoBean IsbnLookupClient
POST /api/books/import/9780134685991 -> 200 {"isbn":"9780134685991","title":"Effective Java","author":"Joshua Bloch","price":"INR 499.00","published_on":"2024-01-01"}
GET /api/books?author=joshua bloch -> 200 [{"isbn":"9780134685991","title":"Effective Java","author":"Joshua Bloch","price":"INR 499.00","published_on":"2024-01-01"}]
beans in this context:
BookController (@RestController)=yes
ApiExceptionHandler (@ControllerAdvice)=yes
PriceJson (@JacksonComponent)=yes
MockMvc=yes
JsonMapper (Jackson 3)=yes
BookService (@Service)=yes
BookRepository (Spring Data)=yes
EntityManagerFactory=yes
DataSource=yes
RestClient.Builder=yes
IsbnLookupClient (@Component)=yes
AuditLogger (@Component)=yes
bean definitions=251
@@ -0,0 +1,25 @@
Each class in lab.slices.failing is run through the JUnit Launcher; this is what its exception says.
(The 'Failed to load ApplicationContext' line carries a long configuration dump with object hashes; it is cut at the first '['.
The module directory is shown as <module>.)
== MissingMockBeanFailure
exception chain: IllegalStateException -> UnsatisfiedDependencyException -> NoSuchBeanDefinitionException
top message : Failed to load ApplicationContext for
wiring failure : Error creating bean with name 'bookController' defined in file [<module>/target/classes/lab/slices/BookController.class]: Unsatisfied dependency expressed through constructor parameter 0: No qualifying bean of type 'lab.slices.BookService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
== ServiceInDataJpaFailure
exception chain: UnsatisfiedDependencyException -> NoSuchBeanDefinitionException
wiring failure : Error creating bean with name 'lab.slices.failing.ServiceInDataJpaFailure': Unsatisfied dependency expressed through field 'service': No qualifying bean of type 'lab.slices.BookService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
== RepositoryInWebMvcFailure
exception chain: UnsatisfiedDependencyException -> NoSuchBeanDefinitionException
wiring failure : Error creating bean with name 'lab.slices.failing.RepositoryInWebMvcFailure': Unsatisfied dependency expressed through field 'repository': No qualifying bean of type 'lab.slices.BookRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
== PlainComponentInJsonFailure
exception chain: UnsatisfiedDependencyException -> NoSuchBeanDefinitionException
wiring failure : Error creating bean with name 'lab.slices.failing.PlainComponentInJsonFailure': Unsatisfied dependency expressed through field 'audit': No qualifying bean of type 'lab.slices.AuditLogger' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
== ClientWithoutComponentsFailure
exception chain: UnsatisfiedDependencyException -> NoSuchBeanDefinitionException
wiring failure : Error creating bean with name 'lab.slices.failing.ClientWithoutComponentsFailure': Unsatisfied dependency expressed through field 'client': No qualifying bean of type 'lab.slices.IsbnLookupClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
@@ -0,0 +1,3 @@
@WebMvcTest + @EnableJpaAuditing (via @Import), BookService mocked
exception chain: IllegalStateException -> BeanCreationException -> BeanCreationException -> IllegalArgumentException
root cause : JPA metamodel must not be empty
@@ -0,0 +1,32 @@
Class.forName on the Boot 4.1.2 test classpath
@WebMvcTest
old: org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest -> NOT FOUND
new: org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest -> present
@AutoConfigureMockMvc
old: org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc -> NOT FOUND
new: org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc -> present
@DataJpaTest
old: org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest -> NOT FOUND
new: org.springframework.boot.data.jpa.test.autoconfigure.DataJpaTest -> present
TestEntityManager
old: org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager -> NOT FOUND
new: org.springframework.boot.jpa.test.autoconfigure.TestEntityManager -> present
@AutoConfigureTestDatabase
old: org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase -> NOT FOUND
new: org.springframework.boot.jdbc.test.autoconfigure.AutoConfigureTestDatabase -> present
@RestClientTest
old: org.springframework.boot.test.autoconfigure.web.client.RestClientTest -> NOT FOUND
new: org.springframework.boot.restclient.test.autoconfigure.RestClientTest -> present
@JsonTest
old: org.springframework.boot.test.autoconfigure.json.JsonTest -> present
new: org.springframework.boot.test.autoconfigure.json.JsonTest -> present
@MockBean
old: org.springframework.boot.test.mock.mockito.MockBean -> NOT FOUND
new: org.springframework.test.context.bean.override.mockito.MockitoBean -> present
@JsonComponent
old: org.springframework.boot.jackson.JsonComponent -> NOT FOUND
new: org.springframework.boot.jackson.JacksonComponent -> present
@SpyBean
old: org.springframework.boot.test.mock.mockito.SpyBean -> NOT FOUND
new: org.springframework.test.context.bean.override.mockito.MockitoSpyBean -> present
@@ -0,0 +1,21 @@
javac against the Boot 4.1.2 test classpath, sources from src/broken/
OldDataJpaTest.java:3: error: package org.springframework.boot.test.autoconfigure.orm.jpa does not exist
OldDataJpaTest.java:4: error: package org.springframework.boot.test.autoconfigure.orm.jpa does not exist
OldDataJpaTest.java:7: error: cannot find symbol
symbol: class DataJpaTest
OldDataJpaTest.java:9: error: cannot find symbol
symbol: class TestEntityManager
location: class lab.slices.OldDataJpaTest
OldRestClientTest.java:3: error: package org.springframework.boot.test.autoconfigure.web.client does not exist
OldRestClientTest.java:6: error: cannot find symbol
symbol: class RestClientTest
OldWebMvcTest.java:3: error: package org.springframework.boot.test.autoconfigure.web.servlet does not exist
OldWebMvcTest.java:4: error: package org.springframework.boot.test.mock.mockito does not exist
OldWebMvcTest.java:7: error: cannot find symbol
symbol: class WebMvcTest
OldWebMvcTest.java:9: error: cannot find symbol
symbol: class MockBean
location: class lab.slices.OldWebMvcTest
10 errors
@@ -0,0 +1,4 @@
Single-argument constructor of each tester in spring-boot-test 4.1.2
JacksonTester wraps tools.jackson.databind.json.JsonMapper
Jackson2Tester cannot be inspected: com.fasterxml.jackson.databind.ObjectMapper is not on the classpath
@@ -0,0 +1,5 @@
Spring Boot 4.1.2: webmvc + data-jpa + restclient starters, and only spring-boot-starter-test for tests
spring-boot jars with 'test' in the name on that classpath:
spring-boot-starter-test-4.1.2.jar
spring-boot-test-4.1.2.jar
spring-boot-test-autoconfigure-4.1.2.jar
@@ -0,0 +1,14 @@
bean WebMvcTest JsonTest RestClientTest DataJpaTest SpringBootTest
BookController (@RestController) yes no no no yes
ApiExceptionHandler (@ControllerAdvice) yes no no no yes
PriceJson (@JacksonComponent) yes yes yes no yes
MockMvc yes no no no yes
JsonMapper (Jackson 3) yes yes yes no yes
BookService (@Service) yes no no no yes
BookRepository (Spring Data) no no no yes yes
EntityManagerFactory no no no yes yes
DataSource no no no yes yes
RestClient.Builder no no yes no yes
IsbnLookupClient (@Component) no no yes no yes
AuditLogger (@Component) no no no no yes
bean definitions 126 35 53 80 251
@@ -0,0 +1,7 @@
Context startup time per test class (one class per mvn run; indicative, varies between runs)
Started JsonSliceTest in 1.132 seconds
Started RestClientSliceTest in 1.521 seconds
Started WebMvcSliceTest in 2.619 seconds
Started DataJpaSliceTest in 3.173 seconds
Started FullContextTest in 4.344 seconds