java - 为什么删除在应用程序中有效但在测试中无效?

标签 java testing spring-data-jpa mockmvc

这是我的案例。

Category.java

@Getter
@Entity
@NoArgsConstructor
public class Category {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;
  private String name;

  @ManyToOne
  @JoinColumn(name = "masterCategory.id")
  private MasterCategory masterCategory;

  @OneToMany(mappedBy = "category", cascade = CascadeType.ALL, orphanRemoval = true)
  private List<Expense> expenses = new ArrayList<>();

}

Expense.java

@Getter
@Entity
@NoArgsConstructor
public class Expense {

  @Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  private long id;
  private BigDecimal amount;
  private String itemName;
  private LocalDateTime expenseDate;
  private String shopName;
  private boolean isIncome;

  @ManyToOne
  @JoinColumn(name = "shop.id")
  private Shop shop;

  @ManyToOne
  @JoinColumn(name = "bankingAccount.id")
  private BankingAccount bankingAccount;

  @ManyToOne
  @JoinColumn(name="category.id")
  private Category category;

  @ManyToOne
  @JoinColumn(name = "userAccount.id")
  private UserAccount userAccount;

  @ManyToOne
  @JoinColumn(name = "userGroup.id")
  private UserGroup userGroup;

}

正如我们所见,它们通过关系链接在一起。 我还为每个类提供了简单的服务、存储库和 Controller (spring boot)。 CategoryService 包含删除 Controller 的方法。它也很简单。

Category category = categoryRepository.selectCategory(getLoggedUsername(),groupId,masterCatId,categoryId);
categoryRepository.delete(category);
return categoryConverter.toMinimalDto(category);

当我运行该应用程序时,一切正常,它从数据库中删除了类别,并删除了与该类别相关的费用。 有一天,我决定编写测试,因为我厌倦了手动检查所有内容。测试方法如下:

@Test
@WithMockUser(username = LOGIN)
public void shouldDeleteCategoryAndConnectedExpenses__andReturn200() throws Exception {
    //given
    mvc.perform(get("/api/budget/1/master/1"))
            .andExpect(status().isOk())
            .andExpect(content().json(testUtil.openJson("categories/categoriesFromSelectedBudget.json")));
    mvc.perform(get("/api/budget/1/master/1/category/1/expense"))
            .andExpect(status().isOk())
            .andExpect(content().json(testUtil.openJson("expenses/expensesFromCategory1.json")));
    //when
    mvc.perform(delete("/api/budget/1/master/1/category/1"))
            .andExpect(status().isOk());
    //then
    mvc.perform(get("/api/budget/1/master/1"))
            .andExpect(status().isOk())
            .andExpect(content().json(testUtil.openJson("categories/categoriesAfterDelete.json")));
    mvc.perform(get("/api/budget/1/master/1/category/1/expense"))
            .andExpect(status().isNotFound());
}

我有一个特殊的 postgresDB 用于测试,在这里我检查 delete 是否真的在做它的工作。我通过检查响应 json 是否是我想要的来做到这一点。简单的东西。

  • 第一个 get (categoriesFromSelectedBudget.json) 包含 3 个元素
  • 第三个 get (categoriesAfterDelete.json) 包含 2 个元素。

这些 json 是 100% 正确的。

问题是:为什么当应用程序运行时,一切正常(我可以看到带有删除的 SQL,正确的行从数据库中删除)但是当运行测试时抛出以下异常:

java.lang.AssertionError: []: Expected 2 values but got 3

在测试中,delete 给我 http 200 但它显然没有删除该元素。也没有带删除的 SQL。为什么?我做错了什么?

最佳答案

感谢提供线索。经过一些调试后,我意识到由于测试类之上的 @Transactional,测试行为如此。我这样做是为了在每种方法之后刷新数据库。我用 @DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD) 替换了它,一切似乎都正常。

关于java - 为什么删除在应用程序中有效但在测试中无效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56701510/

相关文章:

testing - Jmeter : How to test a website to render a page regardless of the content

java - Spring 数据 JPA : Named method without JpaRepository

java - 在我的项目中使用预定义的类名 String

javascript - Jasmine 的错误方法http测试( Angular 7)

java - 通过jhipster向实体添加字段

unit-testing - 在 iTextSharp 中测试代码

java - Spring Boot - 如何创建不同 JpaRepository 接口(interface)的工厂

java - 无法写入 JSON :Infinite recursion(StackOverflowError)nested exception is com. fastxml.jackson.databind.JsonMappingException:无限递归

c# - SOAP 是简单对象访问协议(protocol)还是面向服务的应用程序平台?

java - Cassandra 更新无法正常工作