成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring、Spring Boot和TestNG測試指南 - 測試關(guān)系型數(shù)據(jù)庫

Meils / 3251人閱讀

摘要:地址提供了對的支持,能夠讓我們很方便對關(guān)系型數(shù)據(jù)庫做集成測試。如果想要在打包的時候跳過集成測試,只需要。例子使用因為使用了來做集成測試,得益于其機制,不需要自己構(gòu)建和的。

Github地址

Spring Test Framework提供了對JDBC的支持,能夠讓我們很方便對關(guān)系型數(shù)據(jù)庫做集成測試。

同時Spring Boot提供了和Flyway的集成支持,能夠方便的管理開發(fā)過程中產(chǎn)生的SQL文件,配合Spring已經(jīng)提供的工具能夠更方便地在測試之前初始化數(shù)據(jù)庫以及測試之后清空數(shù)據(jù)庫。

本章節(jié)為了方便起見,本章節(jié)使用了H2作為測試數(shù)據(jù)庫。

注意:在真實的開發(fā)環(huán)境中,集成測試用數(shù)據(jù)庫應該和最終的生產(chǎn)數(shù)據(jù)庫保持一致,這是因為不同數(shù)據(jù)庫的對于SQL不是完全相互兼容的,如果不注意這一點,很有可能出現(xiàn)集成測試通過,但是上了生產(chǎn)環(huán)境卻報錯的問題。

因為是集成測試,所以我們使用了maven-failsafe-plugin來跑,它和maven-surefire-plugin的差別在于,maven-failsafe-plugin只會搜索*IT.java來跑測試,而maven-surefire-plugin只會搜索*Test.java來跑測試。

如果想要在maven打包的時候跳過集成測試,只需要mvn clean install -DskipITs。

被測試類

先介紹一下被測試的類。

Foo.java:

public class Foo {

  private String name;

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }
}

FooRepositoryImpl.java:

@Repository
public class FooRepositoryImpl implements FooRepository {

  private JdbcTemplate jdbcTemplate;

  @Override
  public void save(Foo foo) {
    jdbcTemplate.update("INSERT INTO FOO(name) VALUES (?)", foo.getName());
  }

  @Override
  public void delete(String name) {
    jdbcTemplate.update("DELETE FROM FOO WHERE NAME = ?", name);
  }

  @Autowired
  public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
    this.jdbcTemplate = jdbcTemplate;
  }

}
例子1:不使用Spring Testing提供的工具

Spring_1_IT_Configuration.java:

@Configuration
@ComponentScan(basePackageClasses = FooRepository.class)
public class Spring_1_IT_Configuration {

  @Bean(destroyMethod = "shutdown")
  public DataSource dataSource() {

    return new EmbeddedDatabaseBuilder()
        .generateUniqueName(true)
        .setType(EmbeddedDatabaseType.H2)
        .setScriptEncoding("UTF-8")
        .ignoreFailedDrops(true)
        .addScript("classpath:me/chanjar/domain/foo-ddl.sql")
        .build();
  }

  @Bean
  public JdbcTemplate jdbcTemplate() {

    return new JdbcTemplate(dataSource());

  }
}

Spring_1_IT_Configuration中,我們定義了一個H2的DataSource Bean,并且構(gòu)建了JdbcTemplate Bean。

注意看addScript("classpath:me/chanjar/domain/foo-ddl.sql")這句代碼,我們讓EmbeddedDatabase執(zhí)行foo-ddl.sql腳本來建表:

CREATE TABLE FOO (
  name VARCHAR2(100)
);

Spring_1_IT.java:

@ContextConfiguration(classes = Spring_1_IT_Configuration.class)
public class Spring_1_IT extends AbstractTestNGSpringContextTests {

  @Autowired
  private FooRepository fooRepository;

  @Autowired
  private JdbcTemplate jdbcTemplate;

  @Test
  public void testSave() {

    Foo foo = new Foo();
    foo.setName("Bob");
    fooRepository.save(foo);

    assertEquals(
        jdbcTemplate.queryForObject("SELECT count(*) FROM FOO", Integer.class),
        Integer.valueOf(1)
    );

  }

  @Test(dependsOnMethods = "testSave")
  public void testDelete() {

    assertEquals(
        jdbcTemplate.queryForObject("SELECT count(*) FROM FOO", Integer.class),
        Integer.valueOf(1)
    );

    Foo foo = new Foo();
    foo.setName("Bob");
    fooRepository.save(foo);

    fooRepository.delete(foo.getName());
    assertEquals(
        jdbcTemplate.queryForObject("SELECT count(*) FROM FOO", Integer.class),
        Integer.valueOf(0)
    );
  }

}

在這段測試代碼里可以看到,我們分別測試了FooRepositorysavedelete方法,并且利用JdbcTemplate來驗證數(shù)據(jù)庫中的結(jié)果。

例子2:使用Spring Testing提供的工具

在這個例子里,我們會使用JdbcTestUtils來輔助測試。

Spring_2_IT_Configuration.java:

@Configuration
@ComponentScan(basePackageClasses = FooRepository.class)
public class Spring_2_IT_Configuration {

  @Bean
  public DataSource dataSource() {

    EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
        .generateUniqueName(true)
        .setType(EmbeddedDatabaseType.H2)
        .setScriptEncoding("UTF-8")
        .ignoreFailedDrops(true)
        .addScript("classpath:me/chanjar/domain/foo-ddl.sql")
        .build();
    return db;
  }

  @Bean
  public JdbcTemplate jdbcTemplate() {

    return new JdbcTemplate(dataSource());

  }

  @Bean
  public PlatformTransactionManager transactionManager() {
    return new DataSourceTransactionManager(dataSource());
  }

}

這里和例子1的區(qū)別在于,我們提供了一個PlatformTransactionManager Bean,這是因為在下面的測試代碼里的AbstractTransactionalTestNGSpringContextTests需要它。

Spring_2_IT.java:

@ContextConfiguration(classes = Spring_2_IT_Configuration.class)
public class Spring_2_IT extends AbstractTransactionalTestNGSpringContextTests {

  @Autowired
  private FooRepository fooRepository;

  @Test
  public void testSave() {

    Foo foo = new Foo();
    foo.setName("Bob");
    fooRepository.save(foo);

    assertEquals(countRowsInTable("FOO"), 1);
    countRowsInTableWhere("FOO", "name = "Bob"");
  }

  @Test(dependsOnMethods = "testSave")
  public void testDelete() {

    assertEquals(countRowsInTable("FOO"), 0);

    Foo foo = new Foo();
    foo.setName("Bob");
    fooRepository.save(foo);

    fooRepository.delete(foo.getName());
    assertEquals(countRowsInTable("FOO"), 0);

  }

}

在這里我們使用countRowsInTable("FOO")來驗證數(shù)據(jù)庫結(jié)果,這個方法是AbstractTransactionalTestNGSpringContextTestsJdbcTestUtils的代理。

而且要注意的是,每個測試方法在執(zhí)行完畢后,會自動rollback,所以在testDelete的第一行里,我們assertEquals(countRowsInTable("FOO"), 0),這一點和例子1里是不同的。

更多關(guān)于Spring Testing Framework與Transaction相關(guān)的信息,可以見Spring官方文檔 Transaction management。

例子3:使用Spring Boot

Boot_1_IT.java:

@SpringBootTest
@SpringBootApplication(scanBasePackageClasses = FooRepository.class)
public class Boot_1_IT extends AbstractTransactionalTestNGSpringContextTests {

  @Autowired
  private FooRepository fooRepository;

  @Test
  public void testSave() {

    Foo foo = new Foo();
    foo.setName("Bob");
    fooRepository.save(foo);

    assertEquals(countRowsInTable("FOO"), 1);
    countRowsInTableWhere("FOO", "name = "Bob"");
  }

  @Test(dependsOnMethods = "testSave")
  public void testDelete() {

    assertEquals(countRowsInTable("FOO"), 0);

    Foo foo = new Foo();
    foo.setName("Bob");
    fooRepository.save(foo);

    fooRepository.delete(foo.getName());
    assertEquals(countRowsInTable("FOO"), 0);

  }
  
  @AfterTest
  public void cleanDb() {
    flyway.clean();
  }
  
}

因為使用了Spring Boot來做集成測試,得益于其AutoConfiguration機制,不需要自己構(gòu)建DataSource 、JdbcTemplatePlatformTransactionManager的Bean。

并且因為我們已經(jīng)將flyway-core添加到了maven依賴中,Spring Boot會利用flyway來幫助我們初始化數(shù)據(jù)庫,我們需要做的僅僅是將sql文件放到classpath的db/migration目錄下:

V1.0.0__foo-ddl.sql:

CREATE TABLE FOO (
  name VARCHAR2(100)
);

而且在測試最后,我們利用flyway清空了數(shù)據(jù)庫:

@AfterTest
public void cleanDb() {
  flyway.clean();
}

使用flyway有很多好處:

每個sql文件名都規(guī)定了版本號

flyway按照版本號順序執(zhí)行

在開發(fā)期間,只需要將sql文件放到db/migration目錄下就可以了,不需要寫類似EmbeddedDatabaseBuilder.addScript()這樣的代碼

基于以上三點,就能夠?qū)?shù)據(jù)庫初始化SQL語句也納入到集成測試中來,保證代碼配套的SQL語句的正確性

可以幫助你清空數(shù)據(jù)庫,這在你使用非內(nèi)存數(shù)據(jù)庫的時候非常有用,因為不管測試前還是測試后,你都需要一個干凈的數(shù)據(jù)庫

參考文檔

本章節(jié)涉及到的Spring Testing Framework JDBC、SQL相關(guān)的工具:

Transaction management

Executing SQL scripts

和flyway相關(guān)的:

flyway的官方文檔

flway和spring boot的集成

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/70206.html

相關(guān)文章

  • SpringSpring BootTestNG測試指南 - 集成測試中用Docker創(chuàng)建數(shù)據(jù)

    摘要:我們還是會以測試關(guān)系型數(shù)據(jù)庫里的來做集成測試代碼在這里。這個很有用,如果集成測試失敗,那么你還可以連接到數(shù)據(jù)庫查看情況。 原文地址 在測試關(guān)系型數(shù)據(jù)庫一篇里我們使用的是H2數(shù)據(jù)庫,這是為了讓你免去你去安裝/配置一個數(shù)據(jù)庫的工作,能夠盡快的了解到集成測試的過程。 在文章里也說了: 在真實的開發(fā)環(huán)境中,集成測試用數(shù)據(jù)庫應該和最終的生產(chǎn)數(shù)據(jù)庫保持一致 那么很容易就能想到兩種解決方案: 開發(fā)...

    sshe 評論0 收藏0
  • Spring、Spring BootTestNG測試指南 - 使用Mockito

    摘要:例子使用源代碼我們先給了一個的實現(xiàn)然后又規(guī)定了方法的返回值。源代碼也就是說,得益于,我們能夠很方便地對依賴關(guān)系中任意層級的任意做。 Github地址 Mock測試技術(shù)能夠避免你為了測試一個方法,卻需要自行構(gòu)建整個依賴關(guān)系的工作,并且能夠讓你專注于當前被測試對象的邏輯,而不是其依賴的其他對象的邏輯。 舉例來說,比如你需要測試Foo.methodA,而這個方法依賴了Bar.methodB,...

    Alliot 評論0 收藏0
  • Spring、Spring BootTestNG測試指南 - 測試Spring MVC

    摘要:地址提供了,能夠很方便的來測試。同時也提供了更進一步簡化了測試需要的配置工作。本章節(jié)將分別舉例說明在不使用和使用下如何對進行測試。例子測試的關(guān)鍵是使用對象,利用它我們能夠在不需啟動容器的情況下測試的行為。 Github地址 Spring Testing Framework提供了Spring MVC Test Framework,能夠很方便的來測試Controller。同時Spring...

    andong777 評論0 收藏0
  • Spring、Spring BootTestNG測試指南 - @OverrideAutoConfi

    摘要:因為只有這樣才能夠在測試環(huán)境下發(fā)現(xiàn)生產(chǎn)環(huán)境的問題,也避免出現(xiàn)一些因為配置不同導致的奇怪問題。而方法則能夠不改變原有配置不提供新的配置的情況下,就能夠關(guān)閉。 Github地址 在Chapter 1: 基本用法 - 使用Spring Boot Testing工具里提到: 除了單元測試(不需要初始化ApplicationContext的測試)外,盡量將測試配置和生產(chǎn)配置保持一致。比如如果生產(chǎn)...

    elisa.yang 評論0 收藏0
  • Spring、Spring BootTestNG測試指南 - 使用Spring Boot Test

    摘要:地址前面一個部分講解了如何使用工具來測試項目,現(xiàn)在我們講解如何使用工具來測試項目。所以我們可以利用這個特性來進一步簡化測試代碼。因為只有這樣才能夠在測試環(huán)境下發(fā)現(xiàn)生產(chǎn)環(huán)境的問題,也避免出現(xiàn)一些因為配置不同導致的奇怪問題。 Github地址 前面一個部分講解了如何使用Spring Testing工具來測試Spring項目,現(xiàn)在我們講解如何使用Spring Boot Testing工具來測...

    Anshiii 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<