如何在设置集合时测试 json api
How to test json api when collection is Set
我读到在 Hibernate 关系中最好使用 Set 而不是 List。
我创建了两个与一对多相关的实体:
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String name;
@ManyToOne
@JoinColumn(name = "company_id", nullable = false)
private Company company;
}
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String name;
@LazyCollection(LazyCollectionOption.TRUE)
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
private Set<Product> products;
}
在关系@OneToMany set collection private Set products;
然后我尝试测试 return 结果:
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class CompanyControllerTest {
private static final String API_COMPANY = "/api/company/";
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.build();
}
@Test
public void getById() throws Exception {
int id = 1;
this.mockMvc.perform(get(API_COMPANY + id))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("id", is(1)))
.andExpect(jsonPath("$.name", is("Google")))
.andExpect(jsonPath("$.products", hasSize(2)))
.andExpect(jsonPath("$.products[0].id", is(1)))
.andExpect(jsonPath("$.products[0].name", is("search engine")))
.andExpect(jsonPath("$.products[0].company").doesNotExist())
.andExpect(jsonPath("$.products[1].id", is(2)))
.andExpect(jsonPath("$.products[1].name", is("adv.")))
.andExpect(jsonPath("$.products[1].company").doesNotExist());
}
}
但问题是产品列表是不断变化的,因为我用的是Set。
事实证明,测试要么通过要么失败,因为产品的顺序发生了变化。
我的问题是使用Set时如何测试结果。
你可以用[*]得到所有的元素然后给一个Matchers.containsInAnyOrder(T...)全部您要检查的元素。
像这样:
this.mockMvc.perform(get(API_COMPANY + id))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("id", is(1)))
.andExpect(jsonPath("$.name", is("Google")))
.andExpect(jsonPath("$.products", hasSize(2)))
.andExpect(jsonPath("$.products[*].id", Matchers.containsInAnyOrder(1, 2)))
.andExpect(jsonPath("$.products[*].name", Matchers.containsInAnyOrder("search engine", "adv.")))
.andExpect(jsonPath("$.products[*].company").doesNotExist());
我读到在 Hibernate 关系中最好使用 Set 而不是 List。
我创建了两个与一对多相关的实体:
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String name;
@ManyToOne
@JoinColumn(name = "company_id", nullable = false)
private Company company;
}
@Entity
public class Company {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String name;
@LazyCollection(LazyCollectionOption.TRUE)
@OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
private Set<Product> products;
}
在关系@OneToMany set collection private Set products;
然后我尝试测试 return 结果:
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class CompanyControllerTest {
private static final String API_COMPANY = "/api/company/";
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders
.webAppContextSetup(context)
.build();
}
@Test
public void getById() throws Exception {
int id = 1;
this.mockMvc.perform(get(API_COMPANY + id))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("id", is(1)))
.andExpect(jsonPath("$.name", is("Google")))
.andExpect(jsonPath("$.products", hasSize(2)))
.andExpect(jsonPath("$.products[0].id", is(1)))
.andExpect(jsonPath("$.products[0].name", is("search engine")))
.andExpect(jsonPath("$.products[0].company").doesNotExist())
.andExpect(jsonPath("$.products[1].id", is(2)))
.andExpect(jsonPath("$.products[1].name", is("adv.")))
.andExpect(jsonPath("$.products[1].company").doesNotExist());
}
}
但问题是产品列表是不断变化的,因为我用的是Set。 事实证明,测试要么通过要么失败,因为产品的顺序发生了变化。
我的问题是使用Set时如何测试结果。
你可以用[*]得到所有的元素然后给一个Matchers.containsInAnyOrder(T...)全部您要检查的元素。
像这样:
this.mockMvc.perform(get(API_COMPANY + id))
.andExpect(status().isOk())
.andExpect(content().contentType(APPLICATION_JSON_UTF8))
.andExpect(jsonPath("id", is(1)))
.andExpect(jsonPath("$.name", is("Google")))
.andExpect(jsonPath("$.products", hasSize(2)))
.andExpect(jsonPath("$.products[*].id", Matchers.containsInAnyOrder(1, 2)))
.andExpect(jsonPath("$.products[*].name", Matchers.containsInAnyOrder("search engine", "adv.")))
.andExpect(jsonPath("$.products[*].company").doesNotExist());