英文:
Bean Type not being found in in Spring Test package
问题
以下是您提供的内容的翻译:
描述:
**Field profileDoa in com.N2O2.Nitrouz_Studioz.controller.MainController required a bean of type 'com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa' that could not be found. The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)**
操作:
请考虑在您的配置中定义一个类型为 'com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa' 的 bean。
我对为什么会发生这个错误感到困惑,因为我最近只是开始使用Java Spring Boot,并且还在逐渐适应使用Beans。我在测试类中使用了@Autowired注解来自动装配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("正确访问网站会显示主页")
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);
}
}
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";
}
}
public interface ProfileDoa extends JpaRepository<ProfileEntity, Long> {
public ProfileEntity findByEmail(String email);
}
对此有任何帮助都将是有益的。谢谢。
英文:
So here is what the current description of the error gives me.
Description:
Field profileDoa in com.N2O2.Nitrouz_Studioz.controller.MainController required a bean of type 'com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa' that could not be found. The injection point has the following annotations:
- @org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.N2O2.Nitrouz_Studioz.model.profile.ProfileDoa' in your configuration.
I'm sort of lost to why this error is happening as I've only been working with Java Spring Boot recently and still getting used to working with Beans. I've Autowired the Bean in the Test class but it's still throwing the same error.
Here's what I have in my test class and the Controller and 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);
}
Any help on this would be helpful. Thanks.
答案1
得分: 0
使用@WebMvcTest
,您可以编写针对您的Web层的测试。Spring Test将为您创建一个上下文,其中包含测试应用程序的这一部分所需的所有bean,例如使用@Controller
,@RestController
,@ControllerAdvice
,过滤器等注释的类。
所有其他bean都不会为您创建,因为它们不在Web层的范围内。在您的情况下,这是MainController
注入的任何其他bean。
您现在基本上有两个选择:
- 模拟
ProfileDoa
- 使用
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("导航到网站正确显示主页")
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 ProfileEntity();
when(profileDao.findByEmail("THIS_HAS_TO_MATCH_YOUR_MAIL")).thenReturn(databaseResult);
对于选项二,您可以使用@SpringBootTest
和@AutoconfigureMockMvc
的组合来加载整个Spring上下文(所有bean)并使用MockMvc
:
@SpringBootTest
@AutoconfigureMockMvc
public class MainControllerTest {
// 不需要模拟,因为使用了_真正的_ bean
}
在这种情况下,您可能希望使用例如Testcontainers来启动您的测试的数据库。
英文:
With @WebMvcTest
you can write tests for your web layer. Spring Test will create a context for you with all beans that are required to test this slice of your application: e.g. classes annotated with @Controller
, @RestController
, @ControllerAdvice
, filter, etc.
All other beans are not created for you as they are not in the scope of the web layer. In your case, that's any other bean your MainController
injects.
You have basically now two options:
- Mock the
ProfileDoa
- Use a real bean of
ProfileDoa
. This would require a database and more setup on your side.
For option one you can adjust your test like the following:
@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);
}
}
As I don't see any interaction with profileDoa
in your MainController
there is also no need to prepare any mocked method response. If you do however call e.g. profileDao.findByEmail("mail@duke.io")
somewhere, you can use Mockito to prepare the result:
ProfileEntity databaseResult = new ProfileEntitiy();
when(profileDao.findByEmail("THIS_HAS_TO_MATCH_YOUR_MAIL")).thenReturn(databaseResult);
For option two, you can use a combination of @SpringBootTest
and @AutoconfigureMockMvc
to load the whole Spring context (all beans) and make use of MockMvc
:
@SpringBootTest
@AutoconfigureMockMvc
public class MainControllerTest {
// no mocking required as _real_ beans are used
}
Here you might want to use e.g. Testcontainers to start a database for your test.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论