【问题标题】:spring controller test by mock service通过模拟服务进行弹簧控制器测试
【发布时间】:2019-05-23 09:56:33
【问题描述】:

使用 Mocking 和单元测试助手更喜欢 Spring 测试:

模拟服务替换多个依赖项

enter image description here

@Controller
@RequestMapping("/people")
public class PeopleController {
    @Autowired
    protected PersonService personService;
    @GetMapping
    public ModelAndView people(Model model) {
        for (Person person: personService.getAllPeople()) {
            model.addAttribute(person.getName(), person.getAge());
        }
        return new ModelAndView("people.jsp", model.asMap());
    }
}

私有 MockMvc mockMvc:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PeopleControllerTest {
    @Autowired
    PersonService personService;

    private MockMvc mockMvc;

    @Configuration
    static class Config {
        // Other beans
        @Bean
        public PersonService getPersonService() {
            return mock(PersonService.class);
        }
    }
    @Test
    public void testPeople() throws Exception {
        // When
        ResultActions actions = mockMvc.perform(get("/people"));
    }
}

我想运行mockMvc时出错

java.lang.NullPointerException

【问题讨论】:

  • mockMvc 是什么?
  • @Ravi 服务器端 Spring MVC 测试的主要入口点
  • 你能分享这门课吗?

标签: java spring-mvc spring-boot junit mockito


【解决方案1】:

执行以下步骤:

  1. 创建服务模拟而不是服务原始 (“PersonServiceMock”)

  2. 用服务模拟替换服务原始

        @Autowired
        PersonService personService;
    
        @Autowired
        PeopleController peopleController;
    
        private MockMvc mockMvc;
    
        @Before
        public void setup() {
        peopleController = new PeopleController(new personServiceMock());
        mvc = MockMvcBuilders.standaloneSetup(peopleController).build();
       }    
    
        @Configuration
        static class Config {
            // Other beans
            @Bean
            public PersonService getPersonService() {
                return mock(PersonService.class);
            }
        }
        @Test
        public void testPeople() throws Exception {
            // When
            ResultActions actions = mockMvc.perform(get("/people"));
        }
    }
    

【讨论】:

    【解决方案2】:

    那是因为您从未在代码中初始化mockMvc,而您访问它的点会导致nullPointerException。您需要在使用它之前对其进行初始化,并且由于您的类中的多个测试可能正在使用它,因此最好的方法是使用带有@before 注释的setup() 方法。试试下面:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration
    public class PeopleControllerTest {
    @Autowired
    PersonService personService;
    
    @Autowired
    private WebApplicationContext wac;
    
    private MockMvc mockMvc;
    
    @Before
    public void setup() {
      mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
    
    
    @Configuration
    static class Config {
        // Other beans
        @Bean
        public PersonService getPersonService() {
            return mock(PersonService.class);
        }
    }
    @Test
    public void testPeople() throws Exception {
        // When
        ResultActions actions = mockMvc.perform(get("/people"));
    }
    }
    

    【讨论】:

      【解决方案3】:

      从源代码中我看到 mockMvc 没有任何价值,这就是为什么它在这行代码中命中“java.lang.NullPointerException”:

      ResultActions actions = mockMvc.perform(get("/people"));
      

      为了让它运行,我认为首先需要为 mockMvc 赋予价值。
      通过构造函数:

      @Test
      public void testPeople() throws Exception {
          mockMvc = new MockMvc();
          // When
          ResultActions actions = mockMvc.perform(get("/people"));
      }
      

      或自动接线:

      @Autowired
      MockMvc mockMvc
      

      取决于 MockMvc 类的用途

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-11-22
        相关资源
        最近更新 更多