简体   繁体   English

如何使用Mockito和Junit测试我的Spring Boot Rest API?

[英]how to use mockito and junit to test my spring boot rest api?

I'm new in unit testing and cannot figure out how to test the RESTFul API with Spring using Mockito and Junit, first of all i have preapared the class in which i created two method with @Before and @Test , when i turned in debugging mode it tells me that hasSize collection return 0 not 4. 我是单元测试的新手,无法弄清楚如何使用Mockito和Junit使用Spring测试RESTFul API,首先,我准备了在调试时使用@Before@Test创建两个方法的类。模式,它告诉我hasSize集合返回0而不是4。

@RunWith(SpringJUnit4ClassRunner.class)
public class EmployeControllerTest {
    private MockMvc mockMvc;
    @InjectMocks
    private EmployeController employeController ; 
    @Mock
    private EmployeService employeService ;

    @Before
    public void setUp() throws Exception{
        MockitoAnnotations.initMocks(this);
        mockMvc=MockMvcBuilders.standaloneSetup(employeController).build();
    }
    @Test
    public void testgetAllEmployee() throws Exception{
        List<Employe> employes= Arrays.asList(
                new Employe("Hamza", "Khadhri", "hamza1007", "123")
                ,new Employe("Oussema", "smi", "oussama", "1234") );
        when(employeService.findAll()).thenReturn(employes);
        mockMvc.perform(get("/employe/dto"))
        .andExpect(status().isOk())
        .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
        .andExpect(jsonPath("$", hasSize(4)))
         .andExpect(jsonPath("$[0].nom", is("Hamza")))
         .andExpect(jsonPath("$[0].prenom", is("Khadhri")))
         .andExpect(jsonPath("$[0].login", is("hamza1007")))
         .andExpect(jsonPath("$[0].mp", is("123")))
         .andExpect(jsonPath("$[1].nom", is("Oussema")))
         .andExpect(jsonPath("$[1].prenom", is("smi")))
         .andExpect(jsonPath("$[1].login", is("oussama")))
         .andExpect(jsonPath("$[1].mp", is("1234")));

        verify(employeService,times(1)).findAll();
        verifyNoMoreInteractions(employeService);
    }
}

here is the EmployeController : 这是EmployeController:

    @CrossOrigin(origins = "*", allowedHeaders = "*")
    @RestController
    @RequestMapping("/employe")
    public class EmployeController {
        @Autowired
        private EmployeService employeService;

        @Autowired
        private ModelMapper modelMapper;

        @GetMapping("/dto")
        public List<EmployeDTO> getEmployeDTOList(){
            try {
                    List<Employe> listemp=employeService.findAllEmployeActive();
                    return listemp.stream()
                        .map(emp ->convertToDto(emp))
                        .collect(Collectors.toList());
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            }

        private EmployeDTO convertToDto(Employe emp) {
            EmployeDTO empDto = modelMapper.map(emp, EmployeDTO.class);

            return empDto;
       }
   }

when I turn in debugging mode, it tells me that there is NullPointerException . 当我进入调试模式时,它告诉我存在NullPointerException

How to use properly mockito and junit to succeed the test? 如何正确使用mockitojunit来通过测试?

I see a few potential issues: 我看到一些潜在的问题:

First, you are calling 首先,你在打电话

List<Employe> listemp=employeService.findAllEmployeActive();

in your controller's getEmployeDTOList() , but your Mockito mock is written as: 在控制器的getEmployeDTOList() ,但是您的Mockito模拟编写为:

when(employeService.findAll()).thenReturn(employes)

So, your test might not be working simply because your mock never happens. 因此,您的测试可能无法仅仅因为模拟从未发生而无法正常工作。

Second, you have not mocked the ModelMapper that you autowired in your controller. 其次,您还没有嘲笑在控制器中自动装配的ModelMapper I think Spring will still go ahead and grab that component for you (someone correct me if I'm wrong there), but either way it's not great practice to have your unit tests be dependent on external libraries since you should only be concerned with the controller's functionality. 认为 Spring仍会继续为您获取该组件(如果我错了,请纠正我),但是无论哪种方式,使单元测试依赖于外部库都不是一个好习惯,因为您只需要关注控制器的功能。 It would be better to mock ModelMapper to make it "always" work and write separate tests to validate your mappings. 最好模拟ModelMapper以使其“始终”工作并编写单独的测试以验证您的映射。

I went ahead and made my own version of your code to test things out. 我继续制作了自己的代码版本以进行测试。 I changed hasSize to 2 because you were only using two elements in your example. 我将hasSize更改为2,因为在示例中您仅使用了两个元素。

This test is working for me: 该测试对我有用:

@RunWith(SpringJUnit4ClassRunner.class)
public class EmployeeControllerTest {

    private MockMvc mockMvc;
    @InjectMocks
    private EmployeeController employeeController ; 
    @Mock
    private EmployeeService employeeService;
    @Mock
    private ModelMapper modelMapper;

    @Before
    public void setUp() throws Exception{
        MockitoAnnotations.initMocks(this);
        mockMvc=MockMvcBuilders.standaloneSetup(employeeController).build();
    }

    @Test
    public void testgetAllEmployeeWithModelMapper() throws Exception{
        Employee emp1 = new Employee("Hamza", "Khadhri", "hamza1007", "123");
        Employee emp2 = new Employee("Oussema", "smi", "oussama", "1234");
        List<Employee> Employees= Arrays.asList(emp1, emp2);

        EmployeeDTO dto1 = new EmployeeDTO("Hamza", "Khadhri", "hamza1007", "123");
        EmployeeDTO dto2 = new EmployeeDTO("Oussema", "smi", "oussama", "1234");
        when(modelMapper.map(emp1,EmployeeDTO.class)).thenReturn(dto1);
        when(modelMapper.map(emp2,EmployeeDTO.class)).thenReturn(dto2);

        when(employeeService.findAll()).thenReturn(Employees);


        mockMvc.perform(get("/employe/dto"))
            .andExpect(status().isOk())
            .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
            .andExpect(jsonPath("$", hasSize(2)))
            .andExpect(jsonPath("$[0].nom", is("Hamza")))
            .andExpect(jsonPath("$[0].prenom", is("Khadhri")))
            .andExpect(jsonPath("$[0].login", is("hamza1007")))
            .andExpect(jsonPath("$[0].mp", is("123")))
            .andExpect(jsonPath("$[1].nom", is("Oussema")))
            .andExpect(jsonPath("$[1].prenom", is("smi")))
            .andExpect(jsonPath("$[1].login", is("oussama")))
            .andExpect(jsonPath("$[1].mp", is("1234")));

        verify(employeeService,times(1)).findAll();
        verifyNoMoreInteractions(employeeService);

    }

}

As you can see I create my own DTO objects and pass them back so that modelMapper will always behave as expected for this unit test. 如您所见,我创建了自己的DTO对象,并将它们传递回去,以便modelMapper始终能够像此单元测试一样正常工作。

This is the code that works but it ignores the object emp1 : 这是有效的代码,但它忽略了对象emp1

 public void testgetAllEmployeeWithModelMapper() throws Exception{
         Employe emp1 = new Employe("Hamza", "Khadhri", "hamza1007", "123");
         Employe emp2 = new Employe("Oussem", "smi", "oussama", "1234");
         List<Employe> Employees= Arrays.asList(emp1, emp2);
         EmployeDTO dto1 = new EmployeDTO("Hamza", "Khadhri", "hamza1007", "123");
         EmployeDTO dto2 = new EmployeDTO("Oussem", "smi", "oussama", "1234");
         when(modelMapper.map(emp1,EmployeDTO.class)).thenReturn(dto1);
         when(modelMapper.map(emp2,EmployeDTO.class)).thenReturn(dto2);

         when(employeeService.findAll()).thenReturn(Employees);
         mockMvc.perform(get("/employe/dto"))
         .andExpect(status().isOk())
         .andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
         .andExpect(jsonPath("$", hasSize(2)))
         .andExpect(jsonPath("$[0].nom", is("Hamza")))
         .andExpect(jsonPath("$[0].prenom", is("Khadhri")))
         .andExpect(jsonPath("$[0].login", is("Hamza1007")))
         .andExpect(jsonPath("$[0].mp", is("123")))
         .andExpect(jsonPath("$[1].nom", is("Oussema")))
         .andExpect(jsonPath("$[1].prenom", is("smi")))
         .andExpect(jsonPath("$[1].login", is("oussama")))
         .andExpect(jsonPath("$[1].mp", is("1234")));

     verify(employeeService,times(1)).findAll();
     verifyNoMoreInteractions(employeeService);
    }

}

The cosole shows me that jsonPath("$[0].nom" expect Oussema so when i change it to Oussema which is the object emp2 and it works well. unfortunately it ignores the the object emp1 which contain Hamza , personnaly i just add two constructor in Employe and EmployeDTO. 控制台向我展示了jsonPath(“ $ [0] .nom”期望Oussema,因此当我将其更改为对象emp2的 Oussema时,效果很好。不幸的是,它忽略了包含Hamza的对象emp1 ,我只是添加了两个Employe和EmployeDTO中的构造函数。

this is the class Employe: 这是Employe课程:

 public class Employe implements Serializable {



    @Id
    @Column(unique=true, nullable=false, precision=6)
    private Long id;
    @Column(precision=6)
    private BigDecimal cv;
    @Column(length=254)
    private String nom;
    @Column(length=254)
    private String prenom;
    @Column(length=254)
    private String login;
    @Column(length=254)
    private String mp;
    @Column(length=254)
    private String mail;
    @Column(precision=6)
    private BigDecimal idpointage;
    @Column(length=1)
    private Boolean actif;
    public Employe(String nom, String prenom, String login, String mp) {

        this.nom = nom;
        this.prenom = prenom;
        this.login = login;
        this.mp = mp;
    }

this is the class EmployeDTO: 这是EmployeDTO的类:

public class EmployeDTO {
        private String nom;
        private String prenom;
        private String login ; 
        private String mp ; 


        public EmployeDTO(String nom, String prenom, String login, String mp) {

            this.nom= nom ; 
            this.prenom= prenom ; 
            this.login = login ; 
            this.mp=mp ;
        }

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

相关问题 Spring Boot中针对REST API的JUnit测试失败 - Failing JUnit test for REST API in Spring Boot 如何使用 Mockito 和 JUnit 在 Spring Boot 中测试 POST 方法 - How to test POST method in Spring boot using Mockito and JUnit 如何使用 Mockito 和 JUnit 在 Spring 引导中测试 DELETE 方法 - How to test DELETE method in Spring boot using Mockito and JUnit Spring Boot 2 JUnit Test for rest api在&#39;jwtAuthenticationEntryPoint&#39;失败: - Spring Boot 2 JUnit Test for rest api failed at 'jwtAuthenticationEntryPoint': 使用 Junit 和 Mockito 的 Rest API 的 Junit 测试用例 - Junit test cases for Rest API using Junit and Mockito Spring 开机 rest api mockito + mockm - Spring boot rest api mockito + mockmvc persistence 如何在spring boot中使用JUNIT5和mockito为代码编写DAO类的测试用例 - How to Write the test case for DAO class with JUNIT5 and mockito in spring boot for the code 如何在使用 junit 和 mockito、spring 引导设置电子邮件样式时测试模板引擎 - How to test template engine while styling emails with junit and mockito, spring boot 如何输入和测试catch子句。 春季靴,Junit,Mockito - How to enter and test catch clause. Spring-boot, Junit, Mockito 如何在 Spring boot(Rest api) 中使用 JCS - How to use JCS with Spring boot(Rest api)
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM