在测试控制器方法时,Spring MVC 4.2.6 版似乎没有将模拟服务注入控制器

Posted

技术标签:

【中文标题】在测试控制器方法时,Spring MVC 4.2.6 版似乎没有将模拟服务注入控制器【英文标题】:Spring MVC release 4.2.6 seems does not inject mock service into the controller when testing controller method 【发布时间】:2016-06-20 22:10:25 【问题描述】:

我确实搜索并遵循了为 Spring MVC 控制器创建单元测试类的步骤,但是单元测试运行时带有绿色通过标志,但框架使用原始服务类并调用数据库。我嘲笑了这门课,并使用了 @InjectMocksMockitoAnnotations.initMocks(this)。仍然在测试运行时,控制器使用原始服务对象而不是模拟对象。如果有人能在这方面帮助我,我真的很感激。

这里是UserManager服务类),UserRegisterController控制器),TestUserRegisterControllerTest 类)带有 Eclipse 包结构图片的类

服务:

 @Service
    public class UserManager 

            protected Map<String, String> getAllCertificates() 

                Map<String, String> allCertificates = new HashMap<String, String>();
                //call to database
                return allCertificates;
            




            protected User getUser(int userId) 
                //create session
                User user = session.get(User.class, userId);
                //close session
                return user;
            

            

控制器:

 @Controller
        public class UserRegisterController 

        @Autowired
        private UserManager manager;

        @InitBinder
        public void initBinder(WebDataBinder binder) 
            //do some work

        

        @RequestMapping(value = "/user.html", method = RequestMethod.GET)
        public ModelAndView getUser(@RequestParam(value="userId",   defaultValue="-1") String userId) 
            User user1;
            user1 = this.manager.getUser(Integer.parseInt(userId));
            if (user1 == null) 
                user1 = new User();
            

            ModelAndView view = new ModelAndView("User", "user1", user1);
            view.addObject("allCertificatesMap", this.manager.getAllCertificates());
            return view;
        

        @ModelAttribute
        public void setModelAttribute(Model model) 
            model.addAttribute("PageHeader", "lable.pageHeader");

        

    

测试类:

   @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration("test-spring-dispatcher-servlet.xml")
    @WebAppConfiguration
    public class TestUserRegisterController 

        @Mock
        private UserManager userManager;

        @InjectMocks
        private UserRegisterController userRegisterController;

        @Autowired
        private WebApplicationContext wac;

        private MockMvc mockMvc;

        @Before
        public void setUp() throws Exception 
            // Process mock annotations
            MockitoAnnotations.initMocks(this);

            User user2 = new User();
            user2.setUserId(10006);
            user2.setUserName("Reza");
            user2.setHobby("Quadcopter");
            user2.setPhone("4032376295");

            when(this.userManager.getUser(10006)).thenReturn(user2);
            when(this.userManager.getAllCertificates()).thenReturn(new HashMap<String, String>());

            this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();

        

        @Test
        public void getUser() 
            try 

                this.mockMvc.perform(get("/user.html").param("userId", "10006"))
                    .andExpect(status().isOk())
                    .andExpect(forwardedUrl("/WEB-INF/jsp/User.jsp"))
                    .andExpect(MockMvcResultMatchers.view().name("User"))
                    .andExpect(model().attributeExists("allCertificatesMap"));
             catch (Exception e) 
                // TODO Auto-generated catch block
                e.printStackTrace();
            

    

Package hierarchy

【问题讨论】:

没有 Spring 4.6.2 MVC 版本。 嗨,这是我下载的 spring 库中的自述文件。 “Spring 框架版本 4.2.6.RELEASE”。你是对的,它里面没有 MVC。 它按预期工作。你有 2 个控制器实例,一个带有模拟,一个定期配置。基本上你试图注入模拟的方式是行不通的。创建一个测试上下文,为要模拟的 bean 创建一个模拟,为 bean 提供相同的名称,以便它覆盖原始 bean。 @M.Deinum 感谢您的回复。我只是将 spring-dispatcher-servlet.xml 的内容复制到 test-spring-dispatcher-servlet.xml 并将文本上下文放入我的测试目录中,如包层次结构所示。大概这就是问题的根源。由于我是spring框架的新手,请您提供更详细的回复,我可以按照步骤操作。再次感谢您的帮助。 请不要复制您的上下文,只创建一个覆盖您要模拟的 bean 的上下文。有几个关于堆栈溢出的问题(有答案)表明了这一点。 【参考方案1】:

使用@RunWith(MockitoJUnitRunner.class) 使@InjectMocks 和其他注释起作用

【讨论】:

以上是关于在测试控制器方法时,Spring MVC 4.2.6 版似乎没有将模拟服务注入控制器的主要内容,如果未能解决你的问题,请参考以下文章

Spring 3 MVC Controller 集成测试 - 将 Principal 注入方法

集成测试将整个对象发布到 Spring MVC 控制器

测试一个spring mvc rest控制器

Spring MVC + Shiro + Junit 测试

如何JUnit测试@PreAuthorize注释及其由spring MVC控制器指定的spring EL?

Spring MVC 测试中的空异常体