【问题标题】:Bean Type not being found in in Spring Test package在 Spring Test 包中找不到 Bean 类型
【发布时间】:2020-11-11 09:20:10
【问题描述】:

这就是当前对错误的描述。

说明:

com.N2O2.Nitrouz_Studioz.controller.MainController 中的字段 profileDoa 需要一个无法找到的“com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa”类型的 bean。注入点有以下注解: - @org.springframework.beans.factory.annotation.Autowired(required=true)

行动:

考虑在您的配置中定义一个“com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa”类型的 bean。

我有点不明白为什么会发生这个错误,因为我最近才使用 Java Spring Boot 并且仍然习惯于使用 Beans。我已经在 Test 类中自动装配了 Bean,但它仍然抛出同样的错误。

这是我的测试类以及 Controller 和 ProfileDoa 类中的内容。

@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);
}

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

【问题讨论】:

    标签: java spring-boot unit-testing junit spring-test


    【解决方案1】:

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

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

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

    1. 模拟ProfileDoa
    2. 使用真正的 bean ProfileDoa。这将需要您自己的数据库和更多设置。

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

    @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 为您的测试启动一个数据库。

    【讨论】:

    • 不客气。您能否将此答案标记为已接受,以便进一步的开发人员遇到类似问题时可以轻松找到此答案?
    猜你喜欢
    • 2020-08-28
    • 1970-01-01
    • 2022-01-09
    • 2018-06-12
    • 1970-01-01
    • 2021-05-31
    • 2018-08-13
    • 1970-01-01
    • 2017-11-05
    相关资源
    最近更新 更多