【问题标题】:Spring MVC: How to unit test Model's attribute from a controller method that returns String?Spring MVC:如何从返回字符串的控制器方法中对模型的属性进行单元测试?
【发布时间】:2017-02-28 11:31:02
【问题描述】:

例如,

package com.spring.app;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

/**
 * Handles requests for the application home page.
 */
@Controller
public class HomeController {
    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(final Model model) {
        model.addAttribute("msg", "SUCCESS");
        return "hello";
    }

}

我想使用 JUnit 从home() 测试model 的属性及其值。我可以将返回类型更改为ModelAndView 以使其成为可能,但我想使用String,因为它更简单。不过这不是必须的。

有没有在不改变home() 的返回类型的情况下检查model?还是没办法?

【问题讨论】:

    标签: java spring unit-testing spring-mvc junit


    【解决方案1】:

    你可以使用Spring MVC Test:

    mockMvc.perform(get("/"))
                    .andExpect(status().isOk())
                    .andExpect(model().attribute("msg", equalTo("SUCCESS"))) //or your condition
    

    here 是完整的示例

    【讨论】:

    • 并不是说错了,但这是一个集成而不是单元测试。
    • 单元测试地图的目的是什么?因为模型几乎是一张地图
    • 假设控制器包含与视图相关的逻辑,并且您想用单元测试覆盖该逻辑。但可能是他想要一个集成测试并且要求错误的东西。不要将我的评论视为您的不正确或类似的评论。
    • @mh-dev 我只是认为我以不正确的方式理解了问题并且我的答案不相关,只是试图通过控制器单元测试来想象这种情况。所以你必须直接调用控制器方法并将这个模型作为参数传递
    • 我有一个错误,“方法模型()未定义类型 IndexControllerTest”。在我的控制器中,我有 model.addObject
    【解决方案2】:

    我尝试使用副作用来回答问题。

    @Test
    public void testHome() throws Exception {
        final Model model = new ExtendedModelMap();
        assertThat(controller.home(model), is("hello"));
        assertThat((String) model.asMap().get("msg"), is("SUCCESS"));
    }
    

    但我对此仍然不是很有信心。如果这个答案有一些缺陷,请留下一些 cmets 来改进/贬低这个答案。

    【讨论】:

      【解决方案3】:

      您可以为此使用 Mockito。

      例子:

      @RunWith(MockitoJUnitRunner.class) 
      public HomeControllerTest {
      
          private HomeController homeController;
          @Mock
          private Model model;
      
          @Before
          public void before(){
              homeController = new HomeController();
          }
      
          public void testSomething(){
              String returnValue = homeController.home(model);
              verify(model, times(1)).addAttribute("msg", "SUCCESS");
              assertEquals("hello", returnValue);
          }
      
      }
      

      【讨论】:

      • 它正在检查是否调用了addAttribute("msg", "SUCCESS"),但实际上并未检查model。可以改成这样吗? Map<String, String> map = new HashMap<String, String>(); map.put("msg", "SUCCESS"); assertThat(model.asMap(), is(map));
      • Model 本身是一个接口,但您可以做一个简单的实现来满足您的需要,并使用我们这个来代替模拟的 Model。
      猜你喜欢
      • 2019-01-08
      • 2014-12-27
      • 2023-03-15
      • 2011-08-12
      • 2010-12-25
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多