Spring Boot生成Admin用户的GET接口单元测试问题排查
It looks like your unit test is failing because when using @WebMvcTest (a common annotation for controller tests), Spring only initializes web layer components (like your UserController) and doesn’t load data layer beans such as MongoTemplate that your tokenRepo depends on. Let’s walk through two solid solutions to fix this, plus the key technical terms you should know.
Option 1: Mock the TokenRepo Dependency (Unit Test Approach)
For pure unit testing of your controller, you don’t need the actual TokenRepo or MongoTemplate—you can mock the repository instead. This keeps your test fast and focused on the controller’s logic.
Here’s how to adjust your test class:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; import org.springframework.boot.test.mock.mockito.MockBean; import org.springframework.test.web.servlet.MockMvc; @WebMvcTest(UserController.class) public class UserControllerTest { @Autowired private MockMvc mockMvc; // Mock the TokenRepo so Spring doesn't try to create the real one (which needs MongoTemplate) @MockBean private TokenRepo tokenRepo; @Test public void testGenerateAdminUser() throws Exception { // Write your test logic here using mockMvc.perform(...) // You can also define mock behavior for tokenRepo using Mockito.when(...) if needed } }
The @MockBean annotation tells Spring to create a mock instance of TokenRepo and inject it into your UserController, eliminating the need for the real MongoTemplate bean.
Option 2: Full Integration Test with Embedded MongoDB
If you want to test the entire flow (controller → repo → database), you can use an embedded MongoDB instance so you don’t have to connect to a real database.
First, add the embedded MongoDB dependency to your build file:
Maven (pom.xml):
<dependency> <groupId>de.flapdoodle.embed</groupId> <artifactId>de.flapdoodle.embed.mongo</artifactId> <scope>test</scope> </dependency>
Gradle (build.gradle):
testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'
Then, use @SpringBootTest with @AutoConfigureMockMvc to load the full Spring context, which will include MongoTemplate connected to the embedded MongoDB:
import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.web.servlet.MockMvc; @SpringBootTest @AutoConfigureMockMvc public class UserControllerIntegrationTest { @Autowired private MockMvc mockMvc; @Test public void testGenerateAdminUser() throws Exception { // Your test logic here—this will use the real TokenRepo and embedded MongoDB } }
Key Technical Keywords
@WebMvcTest: Spring Boot annotation for focused controller tests (only loads web layer beans)@MockBean: Used to replace a Spring bean with a Mockito mock in test contexts@SpringBootTest: Loads the full Spring application context for integration testing@AutoConfigureMockMvc: Automatically configures MockMvc for testing web endpoints- Embedded MongoDB: In-memory MongoDB instance for testing without a real database
- MockMvc: Spring’s tool for testing REST endpoints without starting a server
内容的提问来源于stack exchange,提问作者dhanyn10

