如何以编程方式为Spring中的集成测试填充测试数据?

时间:2016-01-25 23:02:26

标签: spring spring-boot spring-data spring-test

我正在寻找使用spring / spring boot在集成测试中以编程方式填充测试数据的推荐方法。我正在使用HSQLDB(内存)。

有可能在Spring中执行SQL脚本以进行这样的集成测试:

@Test
@Sql({"/test-schema.sql", "/test-user-data.sql"})
public void userTest {
    // execute code that relies on the test schema and test data
}

我没有编写SQL脚本,而是想在一个集成测试中插入多个测试方法的数据,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = BookstoreApp.class)
@IntegrationTest
public class BookRepositoryTest {
    @Autowired
    private BookRepository bookRepository;

    @Before // not working
    public void setUp() throws Exception {
        bookRepository.save(new Book("Donald Duck 1", "Walt Disney", "0-14-020652-3"));
        bookRepository.save(new Book("Donald Duck 2", "Walt Disney", "0-14-020652-4"));
        bookRepository.save(new Book("Micky Mouse", "Walt Disney", "0-14-020652-5"));
    }

    @Test
    public void findByTitle() {
        List<Book> books = bookRepository.findByTitle("Duck");
        Assert.assertEquals(2, books.size());
    }

    @Test
    public void getByIsbn() {
        Book book = bookRepository.getByIsbn("0-14-020652-4");
        Assert.assertEquals("0-14-020652-4", book.getIsbn());
        Assert.assertEquals("Donald Duck 2", book.getTitle());
    }

}

此示例的每个测试在单独执行时运行正常。但是第二个(getByIsbn)在一起运行时会失败。所以显然@Before是在这里使用的错误注释,因为书籍将被插入两次。

如何强制执行仅执行一次的数据库设置?

1 个答案:

答案 0 :(得分:3)

MethodInfo methodInfo = typeof(ReadOperations).GetMethod("GetWithChildren", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); Type predicateType = predicate.GetType(); MethodInfo genericMethod = methodInfo.MakeGenericMethod(predicateType); Type[] genericArgumentsType = genericMethod.GetGenericArguments(); Debug.WriteLine("Arguments Number:" + genericArgumentsType.Count()); int count = 0; foreach (Type ga in genericArgumentsType) { Console.WriteLine(count++ + " " + ga.GetType()); } Object[] genericArguments = { conn, predicate, true }; genericMethod.Invoke(conn, genericArguments); 替换为@IntegrationTest(在班级)可能会解决您的问题。

推理:

  1. @Transactional启动整个Spring Boot应用程序,但这似乎对您的方案来说太过分了。
  2. @IntegrationTest将导致测试在测试管理的事务中执行,该事务将在测试完成后回滚;在@Transactional方法中执行的代码将在测试管理的事务中执行。
  3. 此致

    Sam( Spring TestContext Framework的作者