vendredi 21 juin 2019

Why is delete working in app but not in tests?

Here's my case.

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;

}

As we can see, they are linked though a relation. I also have simple service, repository and controller (spring boot) for each of these class. CategoryService contains method for deleting controller. Its also quite simple.

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

And when I run the app, everything works perfectly, its removing the category from database, its removing expenses connected to that category. One day I decided to write tests cause I was tired of checking everything manually. Heres the test method:

@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());
}

I have a special postgresDB for tests, here I check if delete is really doing its job. I do this by checking if response jsons are the ones I want them to be. Simple stuff. First get (categoriesFromSelectedBudget.json) contains 3 elements, third get (categoriesAfterDelete.json) contains 2 elements. These jsons are 100% correct. The question is: why when application is run, everything works correctly (I can see SQLs with delete, correct rows are deleted from DB) but when tests are run java.lang.AssertionError: []: Expected 2 values but got 3 is thrown? In test, delete gives me http 200 but it's clearly not deleting the element. Also there are no SQLs with delete. Why? What did I do wrong?

Aucun commentaire:

Enregistrer un commentaire