LocalStack: 本機(jī) Mock AWS 服務(wù)利器

如果代碼中需要與 AWS 服務(wù)(比如 S3)交互, 如何寫單元測(cè)試?

0x00 mock API

既然是調(diào)用 AWS 的 API, 那么可以從 AWS SDK 入手, 通過(guò)開發(fā)語(yǔ)言級(jí)別的 Mock framework, 攔截 API 調(diào)用. 以 Java 訪問(wèn) S3 為例, 使用 Unitils 框架, Mock AmazonS3Client 類.

// 通過(guò) mock AmazonS3Client 
private Mock<AmazonS3Client> mockS3Client = null;

// 約定 API 返回內(nèi)容
this.mockS3Client.returns(objectListingResult).listObjects(request);

這種做法有幾個(gè)缺點(diǎn):

  • 需要開發(fā)語(yǔ)言支持, 如果選擇了 Go, 我也不知道怎么動(dòng)態(tài) Mock
  • 需要自己寫的代碼容易傳入 Mock 過(guò)的 client 代碼, 比如一個(gè)靜態(tài)變量的 AmazonS3Client 怎辦, 咳咳
  • 沒(méi)有真正通過(guò) API 請(qǐng)求服務(wù), 如果 mock 邏輯錯(cuò)誤, 沒(méi)有達(dá)到測(cè)試的目的

0x01 LocalStack:

LocalStack 是開發(fā) JIRA 的公司 Atlassian 開發(fā)的, 用 Python "山寨"了 AWS 的 API, 通過(guò) REST API 提供跟 AWS 一模一樣的服務(wù). 使用起來(lái)也非常簡(jiǎn)單, 直接 docker pull atlassianlabs/localstack 就完成了安裝. 啟動(dòng)也足夠簡(jiǎn)單,

# 8080 端口是 web 使用
# SERVICES 環(huán)境變量用于指定啟動(dòng)的服務(wù)
# 4560-4582 是各個(gè)服務(wù)使用的端口
docker run -p 8080:8080 -p 4560-4582:4560-4582 --name localstack -e SERVICES='s3,web' atlassianlabs/localstack

各個(gè)服務(wù)使用的端口如下:

AWS 的 cli/SDK 都提供一個(gè) endpoint-url(也就是 AWS API server 的 url) 的 hook, 方便的讓我們使用 Localstack. 例如, aws cli 中使用本地的 S3:

# 創(chuàng)建 bucket
aws s3api --endpoint http://localhost:4572  create-bucket --bucket test-bucket

# 執(zhí)行 ls 操作
aws s3 --endpoint http://localhost:4572 ls s3://test-bucket/

為了與 Java/JUnit 集成, LocalStack 還提供了 LocalstackTestRunner, 參見(jiàn)官方示例:

@RunWith(LocalstackTestRunner.class)
public class MyCloudAppTest {

  @Test
  public void testLocalS3API() {
    AmazonS3 s3 = new AmazonS3Client(...);
    s3.setEndpoint(LocalstackTestRunner.getEndpointS3());
    List<Bucket> buckets = s3.listBuckets();
    ...
  }
}

不過(guò)值得提醒的是, 這個(gè) LocalstackTestRunner 從 github 上下載最新的 localstack 并且在本機(jī)安裝, 作為天朝碼農(nóng)你懂的, 因此還是建議使用 docker 方式運(yùn)行 localstack, 非常便捷.

LocalStack 與 gitlab CI 的集成也非常簡(jiǎn)單, 僅需要在前置的 stage 的 services 中定義 localstack 的 image 即可.

LocalStack 的好處也非常明顯:

  • 真正的 REST API 調(diào)用, 不用代碼級(jí)別 Mock SDK, 因此也做到了所有語(yǔ)言通吃
  • 錯(cuò)誤注入, 比如通過(guò) KINESIS_ERROR_PROBABILITY 環(huán)境變量的值指定多大概率扔出 ProvisionedThroughputExceededException 異常. 不過(guò)這種設(shè)計(jì)在 gitlab CI 中就不是很容易集成進(jìn)來(lái), 畢竟這個(gè)環(huán)境變量是 Localstack 進(jìn)程全局的, 如果想同時(shí)測(cè)試正常情況和異常情況, 還是要?jiǎng)觿?dòng)腦筋

總結(jié)

再也沒(méi)有借口不寫 AWS 服務(wù)相關(guān)的測(cè)試代碼了, 不是么.....

-- EOF --

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子躁绸,更是在濱河造成了極大的恐慌缰盏,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件口芍,死亡現(xiàn)場(chǎng)離奇詭異状原,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)诡壁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)荠割,“玉大人妹卿,你說(shuō)我怎么就攤上這事∶镳校” “怎么了夺克?”我有些...
    開封第一講書人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嚎朽。 經(jīng)常有香客問(wèn)我铺纽,道長(zhǎng),這世上最難降的妖魔是什么哟忍? 我笑而不...
    開封第一講書人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任狡门,我火速辦了婚禮,結(jié)果婚禮上锅很,老公的妹妹穿的比我還像新娘其馏。我一直安慰自己,他們只是感情好爆安,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開白布尝偎。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪致扯。 梳的紋絲不亂的頭發(fā)上肤寝,一...
    開封第一講書人閱讀 51,182評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音抖僵,去河邊找鬼鲤看。 笑死,一個(gè)胖子當(dāng)著我的面吹牛耍群,可吹牛的內(nèi)容都是我干的义桂。 我是一名探鬼主播,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼蹈垢,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼慷吊!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起曹抬,我...
    開封第一講書人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤溉瓶,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后谤民,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體堰酿,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年张足,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了触创。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡为牍,死狀恐怖哼绑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情碉咆,我是刑警寧澤凌那,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站吟逝,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏赦肋。R本人自食惡果不足惜块攒,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望佃乘。 院中可真熱鬧囱井,春花似錦、人聲如沸趣避。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至住练,卻和暖如春地啰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背讲逛。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工亏吝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人盏混。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓蔚鸥,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親许赃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子止喷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)混聊,斷路器弹谁,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,077評(píng)論 25 707
  • https://aws.amazon.com/cn/s3/faqs/#sia_anchor Amazon Simp...
    守望者_(dá)1065閱讀 8,254評(píng)論 0 5
  • 本文是GitChat《Serverless 風(fēng)格微服務(wù)的持續(xù)交付(上):架構(gòu)案例》部分內(nèi)容已做修改。文章聊天實(shí)錄請(qǐng)...
    顧宇閱讀 3,213評(píng)論 1 13
  • 5.整數(shù)的同余 一個(gè)固定的整數(shù)d去除整數(shù)(Zi)如果余數(shù)相同技羔,我們則稱這組整數(shù)Zi是模d同余的僵闯,例如,2藤滥,7鳖粟,...
    jackjianshu閱讀 866評(píng)論 0 0