我有一个非常简单的测试用例,其中包含最基本的设置:
@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> {}
试验装置:
@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
}
}
意外行为:
将test class
作为一个整体运行时,只有第一次测试通过,第二次和第三次测试均未通过。
这也导致了@ParameterizedTest
中的问题:
@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();
}
将dataSource更改为@MethodSource
或@CsvSource
后的行为相同。
我尝试在每个测试中初始化数据,但发生了同样的事情:
@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();
}
为什么只有第一个测试通过而后续测试失败呢?我已经尝试使用不同的id
组合传入。但都是相同的行为。
通过这个简单的演示,我得出了一个结论,运行类似的测试会导致问题,即使,测试不应该相互影响?
我知道我不应该测试SpringBoot提供的内置API,但这是我在使用@Parameterized
测试带有多个参数的mybatis时发现的一个问题。
编辑:似乎大多数人都试图通过在每次测试前重新创建数据库来解决这个问题
1条答案
按热度按时间voase2hg1#
它不起作用,因为每次在setUp()方法中删除/保存数据时,ID的计数器都会不断地增加:
对于第一个测试,您将拥有:
但对于第二个,您将获得:
等等...所以正确的方法是保存它们并保存在类级别的变量中,比如:
关于参数化测试,使用自动递增的id,您无法真正提前知道id