I have a dead simple test case with the most basic set up:
@Entity
public class Tags {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true)
private String name;
public Tags(String name) {
this.name = name;
}
}
@Repository
public interface TagsRepository extends JpaRepository<Tags, Integer> {}
Test set up:
@DataJpaTest
public class TagsTest implements WithAssertions {
@Autowired
private TagsRepository tagsRepo;
@BeforeEach
void setUp() {
Tags tag1 = new Tags("tag1");
Tags tag2 = new Tags("tag2");
Tags tag3 = new Tags("tag3");
tagsRepo.saveAll(List.of(tag1, tag2, tag3));
}
@AfterEach
void cleanUp() {
tagsRepo.deleteAll();
}
@Test
void test() {
Tags actual1 = tagsRepo.findById(1).orElse(null);
assertThat(actual1).isNotNull(); // <- passed
}
@Test
void test2() {
Tags actual2 = tagsRepo.findById(1).orElse(null);
assertThat(actual2).isNotNull(); // <- failed
}
@Test
void test3() {
Tags actual3 = tagsRepo.findById(2).orElse(null);
assertThat(actual3).isNotNull(); // <- failed
}
}
Unexpected behavior:
When run test class
as a whole, only the first test passed and second and third test all failed.
And this leads to problem in @ParameterizedTest
as well:
@ParameterizedTest
@ValueSource(ints = { 1, 1, 2 }) // <- second and third test failed
void test4(Integer id) {
Tags actual = tagsRepo.findById(id).orElse(null);
assertThat(actual).isNotNull();
}
Same behavior after changing dataSource to @MethodSource
or @CsvSource
.
I tried to initialize data in each test, but same thing happend:
@Test
void test() {
Tags tag1 = new Tags("tag1");
Tags tag2 = new Tags("tag2");
Tags tag3 = new Tags("tag3");
tagsRepo.saveAll(List.of(tag1, tag2, tag3));
Tags actual1 = tagsRepo.findById(1).orElse(null);
assertThat(actual1).isNotNull();
tagsRepo.deleteAll();
}
Why would only the first test passed and subsequent test failed? I've tried using different combinations of id
passed in. But all the same behavior.
With this simple demo, I came to the conclusion that, running similar test will casue issue, even though, test should not influence each other?
I know I shouldn't test the built-in API provided by SpringBoot out of the box, but this is a issue I discovered when testing mybatis with mutiple params using @Parameterized
.
Edit: Seems like most folks tried to solve this by re-creating database before each test