在JsonPath不工作的情况下执行Junit测试

rbl8hiat  于 9个月前  发布在  其他
关注(0)|答案(1)|浏览(155)

我正在对rest控制器方法addUser()运行单元测试,该方法在没有JSON路径的情况下成功执行。每当我尝试使用jsonPath执行严格的数据Assert以验证JSON文档的内容时,我都会得到错误No value at JSON path“$.first_name”。任何有关如何修复该问题的帮助都将非常感谢。下面是代码示例

@Entity
@Table(name = "users")
public class User extends IdBaseEntity{

    @JsonProperty("first_name")
    @Column(name = "first_name", nullable = false, length = 45)
    @NotBlank(message = "First name cannot be blank")
    @Length(min = 2, max = 45)
    private String firstName;
    
    @JsonProperty("last_name")
    @NotBlank(message = "Last name cannot be blank")
    @Length(min = 2, max = 45)
    @Column(name="last_name", nullable = false, length = 45)
    private String lastName;
    
    
    @NotBlank(message = "Email cannot be blank")
    @Length(min = 2, max = 45)
    @Column(nullable = false, unique = true, length = 45)
    private String email;
    

    @NotBlank(message = "Password name cannot be blank")
    @Length(min = 2, max = 45)
    @Column(nullable = false, length = 45)
    private String password;
    
    @JsonProperty("phone_number")
    @Column(length = 13)
    private String phoneNumber;
    
    @ManyToMany(fetch = FetchType.EAGER)
    @JoinTable(
            name = "users_roles",
            joinColumns = @JoinColumn(name ="user_id"),
            inverseJoinColumns = @JoinColumn(name="role_id")
            )
    private Set<Role> roles = new HashSet<>();
    
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public void setPhoneNumber(String phoneNumber) {
        this.phoneNumber = phoneNumber;
    }

    @Override
    public String toString() {
        return "User [firstName=" + firstName + ", lastName=" + lastName + ", email=" + email + ", password=" + password
                + ", phoneNumber=" + phoneNumber + "]";
    }
    
}

字符串
服务接口

public interface UserService {
    
    public User addUser(User user); 
    
}


服务类

@Service
public class UserServiceImpl implements UserService{
    
    private UserRepository userRepo;
    
    @Autowired
    public UserServiceImpl(UserRepository userRepo) {
        this.userRepo = userRepo;
    }

    @Override
    public User addUser(User user) {
        return userRepo.save(user);
    }
    
}


restcontroller类

@RestController
@RequestMapping("/api/v1/users")
public class UserRestApiController {

    private UserServiceImpl userService;
    
    public UserRestApiController(UserServiceImpl userService) {
        this.userService = userService;
    }
    
    @PostMapping
    public ResponseEntity<User> addUser(@RequestBody @Valid User user){
        User newUser = userService.addUser(user);
        
        URI uri = URI.create("/api/v1/users");
        
        return ResponseEntity.created(uri).body(newUser);
    }
    
}


测试类

@WebMvcTest(UserRestApiController.class)
public class UserRestApiControllerTest {
    
    //end point uri
    private static final String END_POINT_PATH = "/api/v1/users";
    
    @MockBean 
    private UserServiceImpl userService;
    
    @Autowired MockMvc mockMvc;
    
    @Autowired ObjectMapper objectMapper;
    
    @Test
    public void testAddUserShouldReturn201Created() throws Exception {
    
        User user = new User();
        user.setFirstName("James");
        user.setLastName("Kwarteng");
        user.setEmail("[email protected]");
        user.setPassword("23464433");
        user.setPhoneNumber("04233455");
        
        //fakes the UserServiceImpl class
        Mockito.when(userService.addUser(user)).thenReturn(user);
        
        //convert user object to json object 
        String bodyContent = objectMapper.writeValueAsString(user);
        
        //perform http request
        mockMvc.perform(post(END_POINT_PATH).contentType("application/json").content(bodyContent))
            .andExpect(status().isCreated())
            .andExpect(jsonPath("$.first_name", is("James")))
            .andDo(print());
        
    }
}


运行测试后出现错误。错误代码的一部分被省略

java.lang.AssertionError: No value at JSON path "$.first_name"
    at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.java:302)
    at org.springframework.test.util.JsonPathExpectationsHelper.assertExistsAndReturn(JsonPathExpectationsHelper.java:326)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:452)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)
Caused by: java.lang.IllegalArgumentException: json can not be null or empty
    at com.jayway.jsonpath.internal.Utils.notEmpty(Utils.java:401)

stszievb

stszievb1#

json can not be null or empty。它不适用于jsonPath,因为响应体始终为空,但状态为201。
Mockito.when...thenReturn不会在控制器类中传播。

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Location:"/api/v1/users"]
     Content type = null
             Body = 
    Forwarded URL = null
   Redirected URL = /api/v1/users
          Cookies = []

字符串
您需要通过添加@ExtendWith(MockitoExtension.class)而不是@WebMvcTest(UserRestApiController.class)来涉及Mockito。第二步是通过注册UserRestApiController@Controller示例来构建MockMvc示例。
下面是工作的固定代码。

@ExtendWith(MockitoExtension.class)
class UserRestApiControllerTest {

    private static final String END_POINT_PATH = "/api/v1/users";

    @InjectMocks
    private UserRestApiController userRestApiController;

    @Mock
    private UserServiceImpl userService;

    private MockMvc mockMvc;

    @BeforeEach
    public void setUp() {
        mockMvc = MockMvcBuilders.standaloneSetup(userRestApiController).build();
    }

    @Test
    void testAddUserShouldReturn201Created() throws Exception {

        User user = new User();
        user.setFirstName("James");
        user.setLastName("Kwarteng");
        user.setEmail("[email protected]");
        user.setPassword("23464433");
        user.setPhoneNumber("04233455");

        //fakes the UserServiceImpl class
        Mockito.when(userService.addUser(any(User.class))).thenReturn(user);

        //convert user object to json object
        String bodyContent = new ObjectMapper().writeValueAsString(user);

        //perform http request
        mockMvc.perform(MockMvcRequestBuilders.post(END_POINT_PATH).contentType("application/json").content(bodyContent))
                .andExpect(status().isCreated())
                .andExpect(jsonPath("$.first_name").value("James"))
                .andExpect(jsonPath("$.last_name").value("Kwarteng"))
                .andExpect(jsonPath("$.email").value("[email protected]"))
                .andExpect(jsonPath("$.password").value("23464433"))
                .andExpect(jsonPath("$.phone_number").value("04233455"))
                .andDo(print());
    }
}


MockHttpServlet响应:

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Location:"/api/v1/users", Content-Type:"application/json"]
     Content type = application/json
             Body = {"email":"[email protected]","password":"23464433","first_name":"James","last_name":"Kwarteng","phone_number":"04233455"}
    Forwarded URL = null
   Redirected URL = /api/v1/users
          Cookies = []

相关问题