91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

springboot中如何實現單元測試

發布時間:2021-08-06 15:08:55 來源:億速云 閱讀:187 作者:Leah 欄目:編程語言

springboot中如何實現單元測試,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

一、概述

一個功能的全鏈路測試,往往要依賴于很多外部組件,如數據庫、redis、kafka、第三方接口等,單元測試的執行環境有可能受網絡限制沒有辦法訪問這些外部服務。因此,我們希望通過一些技術手段,能夠用單元測試技術進行完整的功能測試,而不依賴于外部服務。

二、REST接口的測試

springboot提供了testRestTemplate工具用于在單元測試中測試接口,該工具只需指定接口的相對路徑,不需要指定域名和端口。這個特性非常有用,因為springboot的單元測試運行環境的web服務是一個隨機端口,是通過下面這個注解指定的:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)

以下是通過testRestTemplate測試我們開發的/remote接口的方法:

    @Test
    public void testRemoteCallRest() {
        String resp = testRestTemplate.getForObject("/remote", String.class);
        System.out.println("remote result : " + resp);
        assertThat(resp, is("{\"code\": 200}"));
    }

三、第三方接口的依賴

上面的例子中,我們的remote接口會調用一個第三方接口 http://someservice/foo,我們的構建服務器中有可能受網絡限制,無法訪問這個第三方接口,就會導致單元測試無法執行。我們可以通過springboot提供的 MockRestServiceServer 工具來解決這個問題。

首先定義一個MockRestServiceServer變量

private MockRestServiceServer mockRestServiceServer;

在單元測試的初始化階段進行初始化

    @Before
    public void before() {
        mockRestServiceServer = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();

        this.mockRestServiceServer.expect(manyTimes(), MockRestRequestMatchers.requestTo(Matchers.startsWithIgnoringCase("http://someservice/foo")))
                .andRespond(withSuccess("{\"code\": 200}", MediaType.APPLICATION_JSON));

    }

這樣,當我們的單元測試程序中調用http://someservice/foo接口時,就會固定返回{"code": 200}這個返回值,而不是真正的去訪問這個第三方接口。

四、數據庫的依賴

數據庫的依賴比較簡單,直接使用h3這個嵌入式數據庫就可以,所有的數據庫操作都是在h3這個嵌入式數據庫中執行的。

已gradle配置為例:

testImplementation 'com.h3database:h3'

單元測試配置文件中的數據庫連接使用h3:

spring:
  data:
    url: jdbc:h3:mem:ut;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
    username: sa
    password:

這樣,當我們的單元測試程序中調用http://someservice/foo接口時,就會固定返回{"code": 200}這個返回值,而不是真正的去訪問這個第三方接口。

五、redis的依賴

網上有一個開源的redis mockserver,模仿了大部分的redis指令,我們只需要引入這個redis-mockserver即可。 最初版本是一個國人開發的,示例中引入的是老外fork的一個版本,補充了一些指令,但是找不到源碼了,我又fork了一個版本,補充了setex、zscore兩個指令,有需要的可以自己編譯。代碼連接 https://github.com/qihaiyan/redis-mock

已gradle配置為例:

testImplementation 'com.github.fppt:jedis-mock:0.1.16'

單元測試配置文件中的數據庫連接使用redis mockserver:

spring:
  redis:
    port: 10033

增加一個單獨的redis配置文件,用于在單元測試中啟動redis mockserver:

@TestConfiguration
public class TestRedisConfiguration {

    private final RedisServer redisServer;

    public TestRedisConfiguration(@Value("${spring.redis.port}") final int redisPort) throws IOException {
        redisServer = RedisServer.newRedisServer(redisPort);
    }

    @PostConstruct
    public void postConstruct() throws IOException {
        redisServer.start();
    }

    @PreDestroy
    public void preDestroy() {
        redisServer.stop();
    }
}

六、kafka的依賴

spring提供了一個kafka的測試組件,可以在單元測試期間啟動一個嵌入式的kafka服務EmbeddedKafka,模擬真實的kafka操作。

已gradle配置為例:

testImplementation "org.springframework.kafka:spring-kafka-test"

通過ClassRule初始化EmbeddedKafka,有兩個topic: testEmbeddedIn 和 testEmbeddedOut 。

    private static final String INPUT_TOPIC = "testEmbeddedIn";
    private static final String OUTPUT_TOPIC = "testEmbeddedOut";
    private static final String GROUP_NAME = "embeddedKafkaApplication";

    @ClassRule
    public static EmbeddedKafkaRule embeddedKafkaRule = new EmbeddedKafkaRule(1, true, INPUT_TOPIC, OUTPUT_TOPIC);

    public static EmbeddedKafkaBroker embeddedKafka = embeddedKafkaRule.getEmbeddedKafka();

    private static KafkaTemplate<String, String> kafkaTemplate;

    private static Consumer<String, String> consumer;

    @BeforeClass
    public static void setup() {

        Map<String, Object> senderProps = KafkaTestUtils.producerProps(embeddedKafka);
        DefaultKafkaProducerFactory<String, String> pf = new DefaultKafkaProducerFactory<>(senderProps);
        kafkaTemplate = new KafkaTemplate<>(pf, true);

        Map<String, Object> consumerProps = KafkaTestUtils.consumerProps(GROUP_NAME, "false", embeddedKafka);
        DefaultKafkaConsumerFactory<String, String> cf = new DefaultKafkaConsumerFactory<>(consumerProps);
        consumer = cf.createConsumer();
        embeddedKafka.consumeFromAnEmbeddedTopic(consumer, OUTPUT_TOPIC);
    }

在單元測試程序的配置文件中,可以指定這2個kafka的topic

cloud.stream.bindings:
    handle-out-0.destination: testEmbeddedOut
    handle-in-0.destination: testEmbeddedIn
    handle-in-0.group: embeddedKafkaApplication

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

平潭县| 晋宁县| 汨罗市| 明溪县| 上杭县| 长沙市| 鄂托克前旗| 新平| 萨迦县| 辰溪县| 本溪市| 石门县| 濉溪县| 陆良县| 乐清市| 綦江县| 永登县| 莱阳市| 舞钢市| 衡山县| 保康县| 韶山市| 宁化县| 石景山区| 鹤岗市| 盘山县| 延边| 禄丰县| 晋宁县| 郴州市| 车险| 水富县| 剑川县| 上蔡县| 宿迁市| 新营市| 来凤县| 海盐县| 屯昌县| 荣成市| 江西省|