Home > Blockchain >  Java Unit Testing Http Get test user auto generate
Java Unit Testing Http Get test user auto generate

Time:01-21

I write function in rest to automatically generate user with admin role. Here's the function:

UserController.java

@RestController
@RequestMapping("users")
public class UserController {

    @Autowired
    private UserRepository userRepo;
    @Autowired
    private TokenRepository tokenRepo;
    
    @GetMapping("admin")
    public String getAdmin () {
        JSONObject report = new JSONObject();
        String dataAdmin = userRepo.findByUsername("admin");
        if(dataAdmin == null) {
            User myadmin = new User();
            myadmin.setUsername("admin");
            myadmin.setFirstname("admin");
            myadmin.setLastname("admin");
            myadmin.setEmail("admin@admin");
            myadmin.setRole("admin");
            userRepo.save(myadmin);
            report.put("message", "admin generated");
        } else {
            report.put("message", "admin only generated once");
        }
        return report.toString();
    }

I am trying to follow the instruction from here https://www.springboottutorial.com/unit-testing-for-spring-boot-rest-services. In Unit Testing Http Get Operation section. I am getting several problem and also trying the different solution until I meet this Unit testing a Get request in a spring project from stackoverflow. below is the testing script I've make so far.

package blablaaa.order;

import java.util.ArrayList;
import java.util.List;

import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

import blablaaa.order.controller.UserController;
import blablaaa.order.dao.UserRepository;
import blablaaa.order.model.User;

//@ExtendWith(SpringExtension.class)
//@SpringBootTest
@WebMvcTest(value = UserController.class)
class OrderApplicationTests {
//  
    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserRepository userRepo;

    @Test
    void contextLoads() throws Exception{

        User myadmin = new User();
        myadmin.setUsername("admin");
        myadmin.setFirstname("admin");
        myadmin.setLastname("admin");
        myadmin.setEmail("admin@admin");
        myadmin.setRole("admin");
        
        List<User> myUser = new ArrayList<>();
        myUser.add(myadmin);
        RequestBuilder rb = MockMvcRequestBuilders.get("/users/admin").accept(MediaType.APPLICATION_JSON);
        MvcResult result = mockMvc.perform(rb).andReturn();
        JSONObject expect = new JSONObject();
        expect.put("message", "admin generated");
//      System.out.println(result.toString());
        System.out.println(expect.toString());
//      Assertions.assertTrue(result.toString().contains(expect.toString()));
    }

}

I dont know, how the testing should be written. any keyword related to this?

[update]
Here's my main:

// OrderApplication.java
@SpringBootApplication
@EnableMongoRepositories("blablaaa.order.dao")
public class OrderApplication {

    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }

}

Here's my program error log

Description:

Field tokenRepo in blablaaa.order.controller.UserController required a bean named 'mongoTemplate' that could not be found.

The injection point has the following annotations:
    - @org.springframework.beans.factory.annotation.Autowired(required=true)


Action:

Consider defining a bean named 'mongoTemplate' in your configuration.

CodePudding user response:

The first thing you have to do is to clearly understand what your method getAdmin is doing and secondly clearly identify your dependencies and how they interact in the main method. To finish, you have to define what you want to test, in your case you have two cases. The if case and the else case.

In your test you must define the behavior of your mock with a when().thenReturn()...

Your test method will look like this:

@WebMvcTest(value = UserController.class)
class OrderApplicationTests {

    @Autowired
    private MockMvc mockMvc;
    
    @MockBean
    private UserRepository userRepo;

    @Test
    void contextLoads_whenNotNull() throws Exception{

        User myadmin = new User();
        myadmin.setUsername("admin");
        myadmin.setFirstname("admin");
        myadmin.setLastname("admin");
        myadmin.setEmail("admin@admin");
        myadmin.setRole("admin");

        when(userRepo).thenReturn(myadmin)

        mockMvc.perform(get("/users/admin")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpectAll(
                        status().isOk(),
                        jsonPath("$.message", containsString("admin generated"))
                );
    }

    @Test
    void contextLoads_whenIsNull() throws Exception{

        when(userRepo).thenReturn(null)
        mockMvc.perform(get("/users/admin")
                    .contentType(MediaType.APPLICATION_JSON))
            .andExpectAll(
                    status().isOk(),
                    jsonPath("$.message", containsString("admin only generated once"))
            );
    }
}

For more details: https://www.bezkoder.com/spring-boot-webmvctest/

CodePudding user response:

previously i am laravel user. When i run unit testing, i dont need to run the apps before i can run testing scenario. So i think, the error log tell me that the mongo database is not connected to apps, even the apps itself is not running yet.

So, based on my case, i need to make sure run the apps first, not build. If i only build the apps, the program will remain error.

By default, when you need to build the apps, you need to make sure the apps is already running too. Spring Boot will also run the test case before build the jar file.

first, run the apps

mvn spring-boot:run

then,

  • you can run only the test case
    mvn test
    
  • or build your apps
    mvn clean package
    
  • Related