preface

“This is the first day of my participation in the First Challenge 2022. For details: First Challenge 2022”

Here we analyze spring-Web and Spring-Web MVC.

The spring-WebMVC module is not available for many tests. The spring-WebMVC module is not available for many tests. The spring-WebMVC module is not available for many tests. Unit tests for the Spring framework are mainly written in test for each module.

If we go to test under Spring-WebMVC, we can see that there are also quite a few unit tests written solely.

But there is a problem. Spring-webmvc has a core Servlet called DispatcherServle. Usually servlets are placed in an external container, but if Spring writes unit tests and tests this DispatcherServle, Or any other component, will Tomcat start?

The answer is no, too much trouble.

Since the external container will call the Servlet’s service method, can’t we call it manually?

Sure, but what about parameters? So you have a Mock in Spring.

For example, construct an HttpServletRequest object using MockHttpServletRequest, with parameters specifying how the request is made, and the address.

MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest("GET"."/getUser");
Copy the code

Here is a test of a basic interface.

public class WebMvcTest {
   @org.springframework.stereotype.Controller
   static class UserController {
      @GetMapping("getUser")
      @ResponseBody
      public String getUser(a) {
         return "user"; }}@Test
   public void test(a) throws ServletException, IOException {
      MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest("GET"."/getUser");
      MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();
      AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
      ctx.setServletContext(new MockServletContext());
      ctx.register(UserController.class);
      ctx.refresh();
      DispatcherServlet servlet = new DispatcherServlet(ctx);
      servlet.init(newMockServletConfig()); servlet.service(mockHttpServletRequest, mockHttpServletResponse); }}Copy the code

AssertThat is used to determine whether the result is the expected value.

assertThat(mockHttpServletResponse.getContentAsString()).isEqualTo("user");
Copy the code

Such a unit test is complete.

In an example, such as manually building an AOP, the intercepting pointcut is for all methods under a class marked with LogMethod annotations.

public class WebMvcTest {
   @Target({ElementType.TYPE})
   @Retention(RetentionPolicy.RUNTIME)
   static @interface LogMethod{
   }
   @LogMethod
   @org.springframework.stereotype.Controller
   public static class UserController {
      @GetMapping("getUser")
      @ResponseBody
      public String getUser(a) {
         return "user"; }}private DispatcherServlet initServlet(finalClass<? > controllerClass) throws ServletException {
      DispatcherServlet dispatcherServlet = new DispatcherServlet() {
         @Override
         protected WebApplicationContext createWebApplicationContext(@Nullable WebApplicationContext parent) {
            GenericWebApplicationContext wac = new GenericWebApplicationContext();
            wac.registerBeanDefinition("controller".new RootBeanDefinition(controllerClass));
            DefaultAdvisorAutoProxyCreator autoProxyCreator = new DefaultAdvisorAutoProxyCreator();
            autoProxyCreator.setProxyTargetClass(true);
            autoProxyCreator.setBeanFactory(wac.getBeanFactory());
            wac.getBeanFactory().addBeanPostProcessor(autoProxyCreator);
            Pointcut pointcut = new AnnotationMatchingPointcut(LogMethod.class);
            DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, new MethodBeforeAdvice() {
               @Override
               public void before(Method method, Object[] args, Object target) throws Throwable {
                  System.out.println("Method of entry"+method); }}); wac.getBeanFactory().registerSingleton("advisor", advisor);
            wac.refresh();
            returnwac; }}; dispatcherServlet.init(new MockServletConfig());
      return dispatcherServlet;
   }
   @Test
   public void test(a) throws Exception {
      DispatcherServlet dispatcherServlet = initServlet(UserController.class);
      MockHttpServletRequest request = new MockHttpServletRequest("GET"."/getUser");
      MockHttpServletResponse response = newMockHttpServletResponse(); dispatcherServlet.service(request, response); System.out.println(response.getContentAsString()); }}Copy the code

The same goes for the others.