国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

Meils / 3208人閱讀

摘要:地址提供了對(duì)的支持,能夠讓我們很方便對(duì)關(guān)系型數(shù)據(jù)庫(kù)做集成測(cè)試。如果想要在打包的時(shí)候跳過集成測(cè)試,只需要。例子使用因?yàn)槭褂昧藖碜黾蓽y(cè)試,得益于其機(jī)制,不需要自己構(gòu)建和的。

Github地址

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

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

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

注意:在真實(shí)的開發(fā)環(huán)境中,集成測(cè)試用數(shù)據(jù)庫(kù)應(yīng)該和最終的生產(chǎn)數(shù)據(jù)庫(kù)保持一致,這是因?yàn)椴煌瑪?shù)據(jù)庫(kù)的對(duì)于SQL不是完全相互兼容的,如果不注意這一點(diǎn),很有可能出現(xiàn)集成測(cè)試通過,但是上了生產(chǎn)環(huán)境卻報(bào)錯(cuò)的問題。

因?yàn)槭羌蓽y(cè)試,所以我們使用了maven-failsafe-plugin來跑,它和maven-surefire-plugin的差別在于,maven-failsafe-plugin只會(huì)搜索*IT.java來跑測(cè)試,而maven-surefire-plugin只會(huì)搜索*Test.java來跑測(cè)試。

如果想要在maven打包的時(shí)候跳過集成測(cè)試,只需要mvn clean install -DskipITs

被測(cè)試類

先介紹一下被測(cè)試的類。

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中,我們定義了一個(gè)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)
    );
  }

}

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

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

在這個(gè)例子里,我們會(huì)使用JdbcTestUtils來輔助測(cè)試。

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ū)別在于,我們提供了一個(gè)PlatformTransactionManager Bean,這是因?yàn)樵谙旅娴臏y(cè)試代碼里的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")來驗(yàn)證數(shù)據(jù)庫(kù)結(jié)果,這個(gè)方法是AbstractTransactionalTestNGSpringContextTests對(duì)JdbcTestUtils的代理。

而且要注意的是,每個(gè)測(cè)試方法在執(zhí)行完畢后,會(huì)自動(dòng)rollback,所以在testDelete的第一行里,我們assertEquals(countRowsInTable("FOO"), 0),這一點(diǎn)和例子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();
  }
  
}

因?yàn)槭褂昧薙pring Boot來做集成測(cè)試,得益于其AutoConfiguration機(jī)制,不需要自己構(gòu)建DataSourceJdbcTemplatePlatformTransactionManager的Bean。

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

V1.0.0__foo-ddl.sql:

CREATE TABLE FOO (
  name VARCHAR2(100)
);

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

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

使用flyway有很多好處:

每個(gè)sql文件名都規(guī)定了版本號(hào)

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

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

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

可以幫助你清空數(shù)據(jù)庫(kù),這在你使用非內(nèi)存數(shù)據(jù)庫(kù)的時(shí)候非常有用,因?yàn)椴还軠y(cè)試前還是測(cè)試后,你都需要一個(gè)干凈的數(shù)據(jù)庫(kù)

參考文檔

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

Transaction management

Executing SQL scripts

和flyway相關(guān)的:

flyway的官方文檔

flway和spring boot的集成

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/70206.html

相關(guān)文章

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

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

    sshe 評(píng)論0 收藏0
  • SpringSpring BootTestNG測(cè)試指南 - 使用Mockito

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

    Alliot 評(píng)論0 收藏0
  • SpringSpring BootTestNG測(cè)試指南 - 測(cè)試Spring MVC

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

    andong777 評(píng)論0 收藏0
  • SpringSpring BootTestNG測(cè)試指南 - @OverrideAutoConfi

    摘要:因?yàn)橹挥羞@樣才能夠在測(cè)試環(huán)境下發(fā)現(xiàn)生產(chǎn)環(huán)境的問題,也避免出現(xiàn)一些因?yàn)榕渲貌煌瑢?dǎo)致的奇怪問題。而方法則能夠不改變?cè)信渲貌惶峁┬碌呐渲玫那闆r下,就能夠關(guān)閉。 Github地址 在Chapter 1: 基本用法 - 使用Spring Boot Testing工具里提到: 除了單元測(cè)試(不需要初始化ApplicationContext的測(cè)試)外,盡量將測(cè)試配置和生產(chǎn)配置保持一致。比如如果生產(chǎn)...

    elisa.yang 評(píng)論0 收藏0
  • SpringSpring BootTestNG測(cè)試指南 - 使用Spring Boot Test

    摘要:地址前面一個(gè)部分講解了如何使用工具來測(cè)試項(xiàng)目,現(xiàn)在我們講解如何使用工具來測(cè)試項(xiàng)目。所以我們可以利用這個(gè)特性來進(jìn)一步簡(jiǎn)化測(cè)試代碼。因?yàn)橹挥羞@樣才能夠在測(cè)試環(huán)境下發(fā)現(xiàn)生產(chǎn)環(huán)境的問題,也避免出現(xiàn)一些因?yàn)榕渲貌煌瑢?dǎo)致的奇怪問題。 Github地址 前面一個(gè)部分講解了如何使用Spring Testing工具來測(cè)試Spring項(xiàng)目,現(xiàn)在我們講解如何使用Spring Boot Testing工具來測(cè)...

    Anshiii 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<