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();
}
}
CodePudding user response:
expected: "[com.example.recipesapi.model.Recipe@45f421c] (List12@14983265)" but was: "[com.example.recipesapi.model.Recipe@45f421c] (ArrayList@361483eb)"
Based on the above, the difference is in the collection (List
vs ArrayList
).
Have you tried using .containsExactly
or .containsExactlyInAnyOrder
instead of .isEqualTo
?
Alternatively, try wrapping the expected value into ArrayList
.
CodePudding user response:
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.