Search code examples
javaspring-bootintegration-testing

DataJpaTest - every single test passes but when run all together 1/3 fails


Hello I wanted to test my method from an interface that extends from JpaRepository but I've go a strange behaviour. Every single test passes but when I run them all together the test named shouldFindSingleRecipeByName() doesn't pass and the error is:

expected: "[com.example.recipesapi.model.Recipe@45f421c] (List12@14983265)"
 but was: "[com.example.recipesapi.model.Recipe@45f421c] (ArrayList@361483eb)"
org.opentest4j.AssertionFailedError: 
expected: "[com.example.recipesapi.model.Recipe@45f421c] (List12@14983265)"
 but was: "[com.example.recipesapi.model.Recipe@45f421c] (ArrayList@361483eb)"

I get that there is difference between expected and but was but I don't understand why when i run single test it passes and how to make it pass all together.

@DataJpaTest
class RecipeRepositoryTest {

    @Autowired
    private RecipeRepository recipeRepositoryUnderTest;

    @BeforeEach
    void tearDown() {
        recipeRepositoryUnderTest.deleteAll();
    }

    @Test
    void shouldFindSingleRecipeByName() {
        //given
        String searchName = "Tomato soup";

        Recipe recipe1 = new Recipe(
                1L,
                "Tomato soup",
                "Delicious tomato soup",
                Arrays.asList("1. ", "2. "),
                Arrays.asList("1. ", "2. ")
        );

        Recipe recipe2 = new Recipe(
                2L,
                "Mushrooms soup",
                "Delicious mushrooms soup",
                Arrays.asList("1. ", "2. "),
                Arrays.asList("1. ", "2. ")
        );

        List<Recipe> recipes = List.of(recipe1, recipe2);

        recipeRepositoryUnderTest.saveAll(recipes);

        //when
        List<Recipe> recipesList = recipeRepositoryUnderTest.findRecipeByName(searchName.toLowerCase());

        //then
        assertThat(recipesList).isEqualTo(List.of(recipe1));
    }

    @Test
    void shouldFindTwoRecipesByName() {
        //given
        String searchName = "oup";

        Recipe recipe1 = new Recipe(
                1L,
                "Tomato soup",
                "Delicious tomato soup",
                Arrays.asList("1. ", "2. "),
                Arrays.asList("1. ", "2. ")
        );

        Recipe recipe2 = new Recipe(
                2L,
                "Mushrooms soup",
                "Delicious mushrooms soup",
                Arrays.asList("1. ", "2. "),
                Arrays.asList("1. ", "2. ")
        );

        List<Recipe> recipes = List.of(recipe1, recipe2);

        recipeRepositoryUnderTest.saveAll(recipes);

        //when
        List<Recipe> recipesList = recipeRepositoryUnderTest.findRecipeByName(searchName.toLowerCase());

        //then
        assertThat(recipesList).isEqualTo(List.of(recipe1, recipe2));
    }

    @Test
    void findByNameShouldReturnEmptyListOfRecipes() {
        //given
        String searchName = "Tomato soup";

        //when
        List<Recipe> recipesList = recipeRepositoryUnderTest.findRecipeByName(searchName.toLowerCase());

        //then
        assertThat(recipesList).isEqualTo(List.of());
    }

}

Recipe class code:

@AllArgsConstructor
@NoArgsConstructor
@Getter
@Entity
@Table(name = "Recipes")
public class Recipe {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    @NotNull
    @NotEmpty
    private String name;

    @NotNull
    @NotEmpty
    @NotBlank
    private String description;

    @ElementCollection
    private List<String> ingredients;

    @ElementCollection
    private List<String> directions;

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (o == null || Hibernate.getClass(this) != Hibernate.getClass(o)) return false;
        final Recipe recipe = (Recipe) o;
        return id != null && Objects.equals(id, recipe.id);
    }

    @Override
    public int hashCode() {
        return getClass().hashCode();
    }
} 

Solution

  • Perhaps your tests run in parallel, thus the data might be shared in between multiple tests could lead to unexpected results, depending on the current state of the repository.

    Try to print out each of the elements in the actual and expected lists to verify.