简体   繁体   中英

Unit testing a REST API in Java and Spring

I have a simple Java Spring REST API application and i don't know how can i unit test it. I have read the documentations of JUnit and Mockito, but i couldn't figure it out.

Here is the post method in the StudentController class

@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    public void insertStudent(@RequestBody Student student){
        studentService.insertStudent(student);
    }

And here is the insertStudent method in the StudentService class

public void insertStudent(Student student) {
        studentDao.insertStudent(student);
    }

I use MySQL for database. Should i use database too for unit test? I mean i don't want any integration test. I want only unit test. I use supertest in Node.js and it takes care for all, can i do that with JUnit or Mockito too?

If you want to do unit testing then you would not have to connect to the DB. Connecting to DB's and other external services would be considered integration testing. So the request to the DB would be mocked out when testing your StudentService class.

Second point worth mentioning is that you would test your controller class and you service class separately, but in your case those tests would look very similar.

Below is one way you can test your controller's insertStrundent method.

@RunWith(MockitoJUnitRunner.class)
public class TestStudentContoller {

    @Mock
    StundentService mockStudentService;
    @InjectMocks
    StudentController studentController = new StudentController();

    @Test
    public void testInsertStudent(){

        Student student = new Student();

        studentContoller.insertStudent(student);

        verify(studentService, times(1)).insertStudent(student);
    }

Since you controller's insertStudent method has no if statements and only one branch, there is basically only one test that needs to be performed, basically does the controller call the service.

Another way it can be tested is with Springs MockMvc . The good thing about the MockMvc is that it lets you test the HTTP request. For example in this case you would want to test that your controller's insertStudent method will properly respond to HTTP POST requests with a JSON Student.

@RunWith(MockitoJUnitRunner.class)
public class TestStudentContoller {

    @Mock
    StundentService mockStudentService;
    @InjectMocks
    StudentController studentController = new StudentController();

    MockMvc mockMvc;

    @Before
    public void setup(){
        mockMvc = MockMvcBuilders.standAloneSetup(studentController).build();
    }

    @Test
    public void testInsertStudent(){

        Student student = new Student();

        studentContoller.insertStudent(student);

        mockMvc.perform(post("path/to/insert/student")
            .accept(MediaType.APPLICATION_JSON)
            .andExpect(status().isOk())
            .andExpect(content().string("{}"));//put json student in here

        verify(studentService, times(1)).insertStudent(student);
    }

MockMvc has other cool methods you should explore.

I have a simple Java Spring REST API application

You should really start earlier to think about unittests. The best way to do them is before the production code implements the (new) behavior ( TDD ).

Here is the post method in the StudentController class

 @RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE) public void insertStudent(@RequestBody Student student){ studentService.insertStudent(student); } 

This code is too simple to fail . Writing unittests for such code is a waist of time. Code like this is tested via application or module tests

I would start writing unittests for this code as soon as there is some decision to make (eg: additional calls to other objects depending on the input parameters).

The point here is that unittests do not test code - unittests verify desired behavior (which is expressed in your requirements). So yes: not testing this method reduces the coverage in your reports. But the number any coverage tool calculates is less important than the requirement coverage which no tool can calculate and which you can only guarantee by doing TDD.

You want to mock studentService and have a unit test that verify that when the method insertStudent(Student) of the API is called then there is exactly one call to the service's insertStudent(Student) with the same Student instance.

Then create unit tests for different scenario, ie handling null s etc..

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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