简体   繁体   English

如何使用 Mockito 和 JUnit 在 Spring Boot 中测试 POST 方法

[英]How to test POST method in Spring boot using Mockito and JUnit

I am newbie to Unit testing using JUnit and Mockito in Spring boot framework.我是在 Spring 引导框架中使用 JUnit 和 Mockito 进行单元测试的新手。 I want to test this method.我想测试这个方法。 How to test POST Request method:如何测试 POST 请求方法:

// add Employee
@RequestMapping(method = RequestMethod.POST)
public void addEmployee(@RequestBody Employee employee){
    this.employeeService.addEmployee(employee);
}

Thank you in advance先感谢您

As @merve-sahin rightly pointed out, you can use @WebMvcTest to achieve this.正如@merve-sahin 正确指出的那样,您可以使用@WebMvcTest 来实现这一点。

Look at the following example :看下面的例子:

@RunWith(SpringRunner.class)
@WebMvcTest(YourController.class)
public class YourControllerTest {

    @Autowired MockMvc mvc;
    @MockBean EmployeeService employeeService;

    @Test
    public void addEmployeeTest() throws Exception {

        Employee emp = createEmployee();

        mvc.perform(post("/api/employee")
            .contentType(MediaType.APPLICATION_JSON)
            .content(toJson(emp)))
            .andExpect(status().isOk());
    }
}

In Above code you can mock your dependent service using @MockBean.在上面的代码中,您可以使用 @MockBean 模拟您的依赖服务。 The test will perform post on your custom Employee object and validate the response该测试将对您的自定义 Employee 对象执行 post 并验证响应

You can add headers, authorization while calling perform您可以在调用执行时添加标题,授权

Assuming you using JSON as media type, you can write toJson() method using any json library to convert Employee object into Json string format假设您使用 JSON 作为媒体类型,您可以使用任何 json 库编写 toJson() 方法将 Employee 对象转换为 Json 字符串格式

private String toJson(Employee emp) {

If you are using XML, then you can do the same for XML如果您使用的是 XML,那么您可以对 XML 执行相同的操作

You can validate the response using expectations in chained way.您可以以链式方式使用期望来验证响应。 As rightly pointed out, please checkout MockedMvc link which should help you正如正确指出的那样,请查看 MockedMvc​​ 链接,它应该可以帮助您

Go through this following example:通过以下示例:

@RunWith(SpringJUnit4ClassRunner.class)
public class ApplicationControllerTest {

    @Mock
    EmployeeService employeeService;

    private MockMvc mockMvc;

    @Before
    public void setUp() throws Exception {
        initMocks(this);
        YourController controller = new YourController(employeeService);
        mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    public void addEmployee() throws Exception {
        Employee emp = new Employee("emp_id","emp_name");//whichever data your entity class have

        Mockito.when(employeeService.addEmployee(Mockito.any(Employee.class))).thenReturn(emp);

        mockMvc.perform(MockMvcRequestBuilders.post("/employees")
                .content(asJsonString(emp))
                .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().contentType("application/json;charset=UTF-8"));
    }

    public static String asJsonString(final Object obj) {
        try {
            return new ObjectMapper().writeValueAsString(obj);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

In above given example mock your service class which is required to post the data to your Employee entity class.在上面给出的示例中模拟您的服务类,它需要将数据发布到您的 Employee 实体类。 I'm assuming that you're doing this via controller so you first need to initialize the controller which comes under the @Before annotation.我假设您是通过控制器执行此操作,因此您首先需要初始化@Before 注释下的控制器。

By doing above example you'll be able to post your data into the JSON format.通过执行上面的示例,您将能够将数据发布为 JSON 格式。

  • The below example is using J Unit5, Mockito3.x, spring-boot2.4.4, and assertj3.x以下示例使用 J Unit5、Mockito3.x、spring-boot2.4.4 和 assertj3.x
  • The spring-boot-starter-test dependency from version 2.2.0 already comes with Junit 5 and contains also Hamcrest, assertj, and Mockito libraries.版本 2.2.0 中的 spring-boot-starter-test 依赖项已经随 Junit 5 一起提供,并且还包含 Hamcrest、assertj 和 Mockito 库。
  • In JUnit 5, “Runner” extension points, available in JUnit 4, are replaced by the Extension API.在 JUnit 5 中,JUnit 4 中可用的“Runner”扩展点被扩展 API 取代。
  • You can register the Mockito extension via @ExtendWith.您可以通过@ExtendWith注册 Mockito 扩展
  • Initializes mocks annotated with @Mock annotation so that explicit usage of MockitoAnnotations#initMocks(Object) is not required.初始化用 @Mock 注释注释的模拟,以便不需要显式使用 MockitoAnnotations#initMocks(Object)。
  • From spring-boot 2.1, there is no need to load the SpringExtension using annotation @ExtendWith because it's included as a meta-annotation in these annotations @DataJpaTest, @WebMvcTest, and @SpringBootTest.从 spring-boot 2.1 开始,不需要使用注释 @ExtendWith 加载 SpringExtension,因为它作为元注释包含在这些注释@DataJpaTest、@WebMvcTest 和 @SpringBootTest 中。

Complete example with Github link: https://github.com/jdamit/DemoSpringBootApp.git带有 Github 链接的完整示例: https : //github.com/jdamit/DemoSpringBootApp.git

@WebMvcTest(controllers = UserController.class) @WebMvcTest(controllers = UserController.class)

public class UserControllerTest {公共类 UserControllerTest {

@Autowired
private MockMvc mockMvc;

@Autowired
private ObjectMapper mapper;

@MockBean
private UserServiceImpl userService;

private List<UserDto> users;

private UserDto user;

private String URI = "/users";

@BeforeEach
void setUp(){
    users = List.of(new UserDto("Amit", "Kushwaha", "jdamit2027@gmail.com", "sector 120"),
            new UserDto("Amit", "Kushwaha", "jdamit2027@gmail.com", "sector 120"),
            new UserDto("Amit", "Kushwaha", "jdamit2027@gmail.com", "sector 120"));
    user = new UserDto("Rahul", "Swagger", "rahul.swagger@gmail.com", "sector 120");
}

@Test
//@Disabled
void getUsersTest() throws Exception {

    Mockito.when(userService.getUsers()).thenReturn(users);

    MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get(URI)
            .contentType(MediaType.APPLICATION_JSON)
            .accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk())
            .andReturn();

    Assertions.assertThat(result).isNotNull();
    String userJson = result.getResponse().getContentAsString();
    Assertions.assertThat(userJson).isEqualToIgnoringCase(mapper.writeValueAsString(users));
}

@Test
//@Disabled
void createUserTest() throws Exception {

    Mockito.when(userService.createUser(Mockito.any(UserDto.class))).thenReturn(user);

    MvcResult result = mockMvc.perform(MockMvcRequestBuilders.post(URI)
            .contentType(MediaType.APPLICATION_JSON)
            .content(mapper.writeValueAsString(user).getBytes(StandardCharsets.UTF_8))
            .accept(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk())
            .andReturn();

    Assertions.assertThat(result).isNotNull();
    String userJson = result.getResponse().getContentAsString();
    Assertions.assertThat(userJson).isNotEmpty();
    Assertions.assertThat(userJson).isEqualToIgnoringCase(mapper.writeValueAsString(user));
}

} }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM