在 Spring 测试包中找不到 Bean 类型

Bean Type not being found in in Spring Test package

这是当前错误的描述。

描述:

com.N2O2.Nitrouz_Studioz.controller.MainController 中的字段 profileDoa 需要找不到类型为 'com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa' 的 bean。注入点有以下注解: - @org.springframework.beans.factory.annotation.Autowired(要求=真)

操作:

考虑在您的配置中定义类型为 'com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa' 的 bean。

我有点迷惑为什么会发生此错误,因为我最近才使用 Java Spring Boot,并且仍然习惯使用 Beans。我已经在测试中自动连接了 Bean class 但它仍然抛出同样的错误。

这是我的测试 class 以及控制器和 ProfileDoa class。

@WebMvcTest(MainController.class)
@ContextConfiguration(classes = NitrouzStudiozApplication.class)
public class MainControllerTest {
    @Autowired
    private MockMvc mockMvc;

    ProfileEntity profileEntity;
    @Autowired
    private ProfileDoa profileDoa;

    private MainController mainController;
    @Mock
    private Model model;
    private boolean loggedOut = true;
    private boolean loggedIn = false;

    @BeforeEach
    public void intializeController(){
        mainController = new MainController();
    }

    @Test
    @DisplayName("Navigating to Website Correctly Displays Index page")
    public void loadsIndexPage() throws Exception {
        RequestBuilder request = MockMvcRequestBuilders.get("/");
        MvcResult result = mockMvc.perform(request)
            .andExpect(model().attribute("loggedOut", loggedOut))
            .andExpect(model().attribute("loggedIn", loggedIn))
            .andExpect(model().attribute("profileEntity", "Not logged In"))
            .andReturn();
        Assertions.assertEquals("index", result);
    }
}
@Controller
public class MainController {

    private boolean loggedOut = true;
    private boolean loggedIn = false;
    private ProfileEntity profileEntity;
    @Autowired
    private ProfileDoa profileDoa;

    @RequestMapping("/")
    public String home_page(Model model) {
        model.addAttribute("loggedOut", loggedOut);
        model.addAttribute("loggedIn", loggedIn);
        model.addAttribute("profileEntity", "Not logged In");
        return "index";
    }

    @RequestMapping("/about")
    public String about_page(Model model){
        model.addAttribute("loggedOut", loggedOut);
        model.addAttribute("loggedIn", loggedIn);
        model.addAttribute("profileEntity", "Not logged In");
        return "about";
    }

    @RequestMapping("/signup")
    public String sign_up(){
        return "signup";
    }

    @GetMapping("/signUpForm")
    public String signUpForm(Model model, ProfileEntity profileEntity){
        boolean checked = false;
        model.addAttribute("profileEntity", profileEntity);
        model.addAttribute("join", checked);
        return "signUpForm";
    }

    @RequestMapping("/signUpFormError")
    public String signUpFormError(Model model,
            @ModelAttribute("error") boolean error,
            @ModelAttribute("message") String message,
            ProfileEntity profileEntity){
        boolean checked = false;
        model.addAttribute("join", checked);
        model.addAttribute("error", error);
        model.addAttribute("message", message);
        model.addAttribute("profileEntity", profileEntity);
        return "signUpForm";
    }

    @RequestMapping("/ForgotPasswordPage")
    public String forgotPasswordPage(){
        return "forgotPassword";
    }

    @GetMapping("/Forgot_Password")
    public String ForgotPasswordResponse(){
        return "forgotPassword";
    }
}
@Transactional
public interface ProfileDoa extends JpaRepository<ProfileEntity, Long> {

    public ProfileEntity findByEmail(String email);
}

任何关于此的帮助都会有所帮助。谢谢

使用 @WebMvcTest,您可以为 Web 层编写测试。 Spring Test 将为您创建一个上下文,其中包含测试您的应用程序的这一部分所需的所有 bean:例如类 用 @Controller@RestController@ControllerAdvice、过滤器等注释

不会为您创建所有其他 bean,因为它们不在 web 层 的范围内。在您的情况下,这是您的 MainController 注入的任何其他 bean。

你现在基本上有两个选择:

  1. 模拟 ProfileDoa
  2. 使用ProfileDoa的真实bean。这将需要一个数据库和更多设置。

对于选项一,您可以按如下方式调整您的测试:

@WebMvcTest(MainController.class)
public class MainControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ProfileDoa profileDoa;

    private boolean loggedOut = true;
    private boolean loggedIn = false;

    @Test
    @DisplayName("Navigating to Website Correctly Displays Index page")
    public void loadsIndexPage() throws Exception {
        RequestBuilder request = MockMvcRequestBuilders.get("/");
        MvcResult result = mockMvc.perform(request)
            .andExpect(model().attribute("loggedOut", loggedOut))
            .andExpect(model().attribute("loggedIn", loggedIn))
            .andExpect(model().attribute("profileEntity", "Not logged In"))
            .andReturn();
        Assertions.assertEquals("index", result);
    }
}

由于我在您的 MainController 中没有看到与 profileDoa 的任何交互,因此也无需准备任何模拟方法响应。但是,如果您这样做,请致电profileDao.findByEmail("mail@duke.io") 在某处,你可以使用 Mockito 准备结果:

ProfileEntity databaseResult = new ProfileEntitiy();
when(profileDao.findByEmail("THIS_HAS_TO_MATCH_YOUR_MAIL")).thenReturn(databaseResult);

对于选项二,您可以使用 @SpringBootTest@AutoconfigureMockMvc 的组合来加载整个 Spring 上下文(所有 bean)并使用 MockMvc

@SpringBootTest
@AutoconfigureMockMvc
public class MainControllerTest {

  // no mocking required as _real_ beans are used
}

在这里你可能想使用例如Testcontainers 为您的测试启动数据库。