How to mock remote REST API in unit test with Spring?

后端 未结 6 727
生来不讨喜
生来不讨喜 2020-12-14 00:49

Assume I have made a simple client in my application that uses a remote web service that is exposing a RESTful API at some URI /foo/bar/{baz}. Now I wish to uni

6条回答
  •  感情败类
    2020-12-14 01:03

    Here is a basic example on how to mock a Controller class with Mockito:

    The Controller class:

    @RestController
    @RequestMapping("/users")
    public class UsersController {
    
        @Autowired
        private UserService userService;
    
        public Page getUsers(Pageable pageable) {
            Page page = userService.getAllUsers(pageable);
            List items = mapper.asUserCollectionItems(page.getContent());
            return new PageImpl(items, pageable, page.getTotalElements());
        }
    }
    

    Configure the beans:

    @Configuration
    public class UserConfig {
    
        @Bean
        public UsersController usersController() {
            return new UsersController();
        }
    
        @Bean
        public UserService userService() {
            return Mockito.mock(UserService.class);
        }
    }
    

    The UserCollectionItemDto is a simple POJO and it represents what the API consumer sends to the server. The UserProfile is the main object used in the service layer (by the UserService class). This behaviour also implements the DTO pattern.

    Finally, mockup the expected behaviour:

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(loader = AnnotationConfigContextLoader.class)
    @Import(UserConfig.class)
    public class UsersControllerTest {
    
        @Autowired
        private UsersController usersController;
    
        @Autowired
        private UserService userService;
    
        @Test
        public void getAllUsers() {
            initGetAllUsersRules();
            PageRequest pageable = new PageRequest(0, 10);
            Page page = usersController.getUsers(pageable);
            assertTrue(page.getNumberOfElements() == 1);
        }
    
        private void initGetAllUsersRules() {
            Page page = initPage();
            when(userService.getAllUsers(any(Pageable.class))).thenReturn(page);
        }
    
        private Page initPage() {
            PageRequest pageRequest = new PageRequest(0, 10);
            PageImpl page = new PageImpl<>(getUsersList(), pageRequest, 1);
            return page;
        }
    
        private List getUsersList() {
            UserProfile userProfile = new UserProfile();
            List userProfiles = new ArrayList<>();
            userProfiles.add(userProfile);
            return userProfiles;
        }
    }
    

    The idea is to use the pure Controller bean and mockup its members. In this example, we mocked the UserService.getUsers() object to contain a user and then validated whether the Controller would return the right number of users.

    With the same logic you can test the Service and other levels of your application. This example uses the Controller-Service-Repository Pattern as well :)

提交回复
热议问题