【问题标题】:java.lang.AssertionError: Status expected:<400> but was:<200> Expected :400 Actual :200java.lang.AssertionError:预期状态:<400> 但原为:<200> 预期:400 实际:200
【发布时间】:2021-11-24 21:52:53
【问题描述】:

所以,我今天一直在测试一个springboot MVC,当我运行测试时,我无法通过使用测试来激活错误:


  @Test
    void post_A_User_passwords_do_notMatch() throws  Exception {

         User newUser = new User("TestName", "TestEmail@email.com", "NOT_THE_SAME","password123", true);

        // * Building the request
        RequestBuilder postAUser = MockMvcRequestBuilders.post("/users")
                .contentType(MediaType.APPLICATION_JSON)
                .header("authorization", "Bearer " + accessToken)
                .content(objectMapper.writeValueAsString(newUser));

        // * Sending the request
        ResultActions posting = mockMvc.perform(postAUser);

        // * Analysing the result
        MvcResult mvcResult = posting
                .andExpect(status().isBadRequest())
                .andReturn();


    }

即使我以 JSON 形式通过模拟帖子传递数据,该错误也不会被击中。我得到的只是:

java.lang.AssertionError:预期状态: 但原为: 预计:400 实际:200

所以,我更改了实际的原始实体,以便实例字段具有匹配的密码,然后不匹配的密码,嘿,当实体在实例字段中具有不匹配的密码时,会出现错误。所以,这让我得出的结论是,在调用映射时,将一个空白的用户实体模板传递给服务(嗯,与在用户模型中设置的相同),然后它贯穿业务服务,然后在发生这种情况后将 JSON 数据保存到 repo 中,然后以可以访问的 JSON 格式发送响应。

理想情况下,我希望能够通过 JSON 数据命中错误,这样如果传入数据的两个密码不匹配,则通过用户服务激活错误。

所以,我有一些关于测试、尝试命中错误和输出的问题:

  1. 我是否对实体做出了正确的结论 在没有 JSON 数据的情况下传入。
  2. 如果有任何数据保存在 JAVA 中的 JAVA 端 (IntelliJ) 中,并且它不仅保留在数据库中并作为 JSON 响应返回。
  3. 怎么会遇到错误?

实体,然后是用户控制器和用户服务的相关部分在下面发布。我只是为用户 repo 扩展一个 CRUD 存储库。我已将 spring security 设置为允许所有路径。

package bookapp.backend.model;

import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "users")
@Getter @Setter
public class User {
    @Id // Change to UUID later after testing
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column
    private Integer id;

    @Column
    @JsonProperty("userName")
    private String userName;

    @Column
    private String email;

    @Column
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY, value = "password")
    private String password = "";

    @Transient
    @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
    @Column
    private String passwordConfirmation = "";

    @Column
    private Boolean isAdmin;

    // Relationships

    // reviews
    @OneToMany
    private List<Review>reviewList;

    // Not sure how the relationship between myLibrary and myReadBooks with books will work
    // Leaving this as it is for now, but might have to change annotations etc

    @OneToMany
    private List<Book> myLibrary;

    @OneToMany
    private List<Book> myReadBooks;

    // * Constructors Added for Testing
    public User() {
    }

    public User(String userName, String email, String password, String passwordConfirmation, Boolean isAdmin) {
        this.userName = userName;
        this.email = email;
        this.password = password;
        this.passwordConfirmation = passwordConfirmation;
        this.isAdmin = isAdmin;
    }

    // * ToString Added for Testing
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", userName='" + userName + '\'' +
                ", email='" + email + '\'' +
                ", password='" + password + '\'' +
                ", passwordConfirmation='" + passwordConfirmation + '\'' +
                ", isAdmin=" + isAdmin +
                '}';
    }
}

控制器中的这个控制器方法

 // ! Create a new user
    @PostMapping("/users")
    public User postUser(@RequestBody @Valid User user) { return userService.createUser(user); }


在服务中也有这个方法:

    // ! This method creates a new user in the UserRepo
    public User createUser(User user) {
        // ! Check if password matches the passwordConfirmation

        if (!user.getPassword().equals(user.getPasswordConfirmation())) {
            throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Password does not match password confirmation");
        }

        // ! Check if the user already exists in the UserRepo
//        Optional<User> existingUser = userRepo.findByUsername(user.getUserName());
//        if (existingUser.isPresent()) {
//            throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "A user with that username already exists");
//        }

        // ! Encrypt password with bCrypt
        String encodedPassword = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encodedPassword);

        return userRepo.save(user);
    }

【问题讨论】:

    标签: java spring spring-boot spring-mvc testing


    【解决方案1】:
    @Test
    void post_A_User_ErrorCheck2() throws  Exception {
    
        objectMapper.disable(MapperFeature.USE_ANNOTATIONS);
    
        User newUser = new User("testName", "TestEmail@email.com", "password$DO_NOT_MATCH123","password$123", true);
    
        // *  Building the request
        RequestBuilder postAnUser = MockMvcRequestBuilders
                .post("/users")
                .contentType(MediaType.APPLICATION_JSON)
                .header("authorization", "Bearer " + accessToken)
                .content(objectMapper.writeValueAsString(newUser));
    
        // * Performing the Request
        ResultActions postingAnUser = mockMvc.perform(postAnUser);
    
        // * Analysing the results
        MvcResult testResult = postingAnUser
                .andExpect(status().isNotFound())
                .andReturn();
    }
    

    因此,事实证明,注释实体的 JSON 忽略属性 @JsonProperty(access = JsonProperty.Access.WRITE_ONLY, value = "password") 会阻止数据的序列化。这发生在测试中存在的对象映射器对象上。需要@JsonProperty(access = JsonProperty.Access.WRITE_ONLY) 以防止密码在响应中返回,但在这种情况下,我们使用objectMapper.disable(MapperFeature.USE_ANNOTATIONS) 来允许写入它们。此外,@Test 中的测试有一个错误isBadrequest() 与用户服务中的HttpStatus.NOT_FOUND 错误不匹配。

    【讨论】:

      猜你喜欢
      • 2021-08-05
      • 1970-01-01
      • 1970-01-01
      • 2017-01-20
      • 2019-02-26
      • 2017-12-25
      • 2022-07-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多