国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Testify Mock 單元測試

這篇具有很好參考價值的文章主要介紹了Testify Mock 單元測試。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Testify 提供了單測方便的斷言能力,這里的斷言是將對代碼實際返回的斷言,代碼的實際輸出和預(yù)期是否一致。下面是 gin-gonic/gin 代碼庫的單測代碼,Testify 還提供了很多其他的方法:

assert.Equal(t, "admin", user)
assert.True(t, found)

單元測試中也會存在不穩(wěn)定的代碼,我們的入?yún)㈦m然保持不變,但每次單測的結(jié)果可能會發(fā)生變化。比如說,我們會調(diào)用第三方的接口,而第三方的接口可能會發(fā)生變化。再比如,代碼中有通過 time.Now() 獲取最近7天內(nèi)的用戶訂單,這個返回結(jié)果本身就是隨當(dāng)前時間變化的。

當(dāng)然,我們肯定不希望每次單測都手動調(diào)整,來“迎合”這類不穩(wěn)定的代碼,這樣不僅疲于奔命,還效率不高。測試上使用 Mock 就可以解決這類問題。這里主要看看如何使用 Testify 的 mock 功能,從下面這個簡單的例子出發(fā):

package main

import (
	"math/rand"
	"time"
)

func DivByRand(numerator int) int {
	rand.Seed(time.Now().Unix())
	return numerator / int(rand.Intn(10))
}

DivByRand 中除以一個隨機數(shù),導(dǎo)致結(jié)果是隨機的,不可預(yù)測的,我們該如何對它進行單測呢?特別強調(diào)下,rand.Seed 方法調(diào)用是必須的,如果不隨機初始化 seed,rand.Intn 每次返回的結(jié)果都是相同的。隨機數(shù)都是基于某個 seed 的隨機數(shù),seed 不變,預(yù)期的隨機數(shù)就是固定不變的。

我們針對隨機方法的部分,做一個接口聲明,以及接口實現(xiàn),來替代代碼中隨機的被除數(shù)。這里mock需要對原函數(shù)做代碼改造,我們一起來看一下調(diào)整過程:

import (
	"github.com/stretchr/testify/mock"
	"testing"
)

// 聲明隨機接口
type randNumberGenerator interface {
    randomInt(max int) int
}

// 聲明接口的實現(xiàn)
type standardRand struct{}

func (s standardRand) randomInt(max int) int {
	rand.Seed(time.Now().Unix())
    return rand.Intn(max)
}

// 修改原有的方法,已經(jīng)修改了原函數(shù)的聲明
func DivByRand(numerator int, r randNumberGenerator) int {
	return numerator / r.randomInt(10)
}

使用 Testify mock 功能

我們聲明一個 mock 結(jié)構(gòu)體,匿名嵌套 mock.Mock。通過嵌套 Mock,結(jié)構(gòu)體就具備了注冊方法,返回預(yù)期結(jié)果的能力。其中,randomInt 的實現(xiàn)對應(yīng)了我們預(yù)期的輸入和輸出關(guān)系。

type mockRand struct {
	mock.Mock
}

func newMockRand() *mockRand { return &mockRand{} }

func (m *mockRand) randomInt(max int) int {
	args := m.Called(max)
	return args.Int(0)
}

最終,我們的單測就變成了下面的樣子,其中的 On 用來對結(jié)構(gòu)體的方法 randomInt 做設(shè)置,Return 對應(yīng)了 args.Int(0)。我們執(zhí)行下面的單測,返回的結(jié)果是恒定的。

func TestDivByRand(t *testing.T) {
	m := newMockRand()
	m.On("randomInt", 10).Return(6)

	t.Log(DivByRand(6, m))
}

Testify Mock 方法實現(xiàn)的核心就是 On 和 Return 方法了,它對應(yīng)的是我們接口的實現(xiàn)。m.Called 函數(shù)的返回值類型為 Arguments,包含了函數(shù)的返回值信息,args.Int(0) 表示獲取 Called 函數(shù)的第一個返回值。On 用來給函數(shù)設(shè)置入?yún)ⅲ琑eturn 用來給函數(shù)設(shè)置出參。

randomInt 方法只返回了一個結(jié)果,一般的函數(shù)還會額外返回 error 信息,來標志函數(shù)執(zhí)行是否出現(xiàn)異常。這種情況可以通過 args.Error(1) 來獲取,表示第二個出參是 error 類型。

從起初的單測,到最后的單測,函數(shù)的方法聲明被修改了。假設(shè)我們要處理的是線上代碼,這樣的改動其實破壞了代碼的穩(wěn)定性,為了單測,我們還需要重新對代碼做回歸測試,確保改動不會對線上環(huán)境產(chǎn)生影響。但這種改動也可以總結(jié)為一種模式,只要按照固定的模式做代碼調(diào)整就可以了:

  1. 針對返回結(jié)果不確定的方法 ,封裝獨立的接口聲明。
  2. 使用 Testify Mock 重新實現(xiàn)這個接口
  3. 使用 Testify Mock 確定性的實現(xiàn)來替代原來的方法。前提是將之前直接調(diào)用方法的地方,修改為接口調(diào)用。

所以,這種情況其實不利于存量代碼的覆蓋率測試,單測最好做到是不要侵入老代碼,避免引入不必要風(fēng)險。但在增量代碼上,我們可以使用這種模式,提前按照接口的模式去做功能實現(xiàn),也就是測試驅(qū)動的意思。

在開發(fā)代碼之前,先想好單測的實現(xiàn),代碼設(shè)計上多了一個維度的考量,也會讓代碼寫的更加有擴展性。

庫的其他 mock 方法

觀察下面的代碼,它用到了更多 testify 庫提供的方法,包括 MatchedBy、Once、AssertNumberOfCalls。不過就數(shù) AssertNumberOfCalls 最簡單了,用來斷言方法的調(diào)用次數(shù)。

mock.MatchedBy(reqSlothFacts) 本來應(yīng)該是傳遞函數(shù) ListAnimalFacts 入?yún)⒌模F(xiàn)在傳遞了 mock.MatchedBy 函數(shù)的執(zhí)行結(jié)果。我們詳細來看一下這幾個方法。

func TestGetSlothsFavoriteSnackOnPage2(t *testing.T) {
    c := newMockClient()
    c.On("ListAnimalFacts", mock.MatchedBy(reqSlothFacts)).
        Return(&page1, nil).
        Once()
    c.On("ListAnimalFacts", mock.MatchedBy(reqSlothFacts)).
        Return(&page2, nil).
        Once()

    favSnack, err := getSlothsFavoriteSnack(c)
    if err != nil {
        t.Fatalf("got error getting sloths' favorite snack: %v", err)
    }

    if favSnack != "hibiscus flowers" {
        t.Errorf(
            "expected favorite snack to be hibiscus flowers, got %s",
            favSnack,
        )
    }

    c.AssertNumberOfCalls(t, "ListAnimalFacts", 2)
}

Once 和 sync.Once 要表示的含義是一致的,表示只能執(zhí)行一次,但多次執(zhí)行 sync.Once 也是沒有問題的,只不過只有第一次生效而已。但 mock 中的 Once 執(zhí)行兩次是會報錯的。如果只是用來限定方法的執(zhí)行次數(shù),想一想,也沒啥好單測的。沿用上面的代碼,我們稍微做些改動

func TestDivByRand(t *testing.T) {
	m := newMockRand()
	m.On("randomInt", 10).Return(6).Once()

	m.randomInt(10)
	m.randomInt(10)
}

執(zhí)行上面的單測,會發(fā)生 panic,提示信息中聲明了:assert: mock: The method has been called over 1 times.。就目前來說,難道除了 panic 就沒有什么更好的方式了?

其實 Once 還有另一個特別有用的功能,就是設(shè)置函數(shù)不同的返回值,還拿 randomInt 函數(shù)來說,如果我們期望,同樣的入?yún)?,第一次調(diào)用 randomInt 返回6, 第二次調(diào)用 randomInt 返回 5 怎么處理。注意,是相同的入?yún)?。我們可以通過這樣的方式就能輸出 6、5。

func TestDivByRand(t *testing.T) {
	m := newMockRand()
	m.On("randomInt", 10).Return(6).Once()
	m.On("randomInt", 10).Return(5).Once()

	t.Log(m.randomInt(10))
	t.Log(m.randomInt(10))
}

當(dāng)然,如果不使用 Once,用下面這種不同的入?yún)?,也能達到相同的效果。改動點主要是 On 方法的第二個參數(shù),以及 Return 方法的返回值。

func TestDivByRand(t *testing.T) {
	m := newMockRand()
	m.On("randomInt", 10).Return(6)
	m.On("randomInt", 9).Return(5)

	t.Log(m.randomInt(10))
	t.Log(m.randomInt(9))
}

最后,我們來看看 MatchedBy 的用法,可以用來校驗方法的入?yún)?。這個方法的使用約束比較多,參數(shù)需要是一個函數(shù),函數(shù)的返回只是 bool 類型,校驗成功返回 true,校驗失敗返回 false。函數(shù)的入?yún)⒕褪欠椒ǖ娜雲(yún)㈩愋?,且只能處理一個參數(shù),如果方法有多個參數(shù),需要聲明多個 MatchedBy。

我們用例子來看一下,我們校驗 randomInt 的參數(shù)必須等于10,如果不等于10,單測又會拋出 panic。整體來看,MatchedBy 的效用不是特別大。

func TestDivByRand(t *testing.T) {
	m := newMockRand()
	m.On("randomInt", mock.MatchedBy(func(num int) bool {
		return num == 10
	})).Return(6)

	t.Log(m.randomInt(10))
}

本文主要是參照 Mocks in Go tests with Testify Mock 的示例,不過原文章講的過于詳細文章來源地址http://www.zghlxwxcb.cn/news/detail-438755.html

到了這里,關(guān)于Testify Mock 單元測試的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • mock寫單元測試和查數(shù)據(jù)庫的單元測試

    mock寫單元測試和查數(shù)據(jù)庫的單元測試

    一:mock方式 在測試類上添加注解 將需要測試的類bean添加進來,該類中的其他bean也添加進來 給被測試類中用到的參數(shù)、返回值類創(chuàng)建對象 創(chuàng)建BeforeEach和AfterEach方法,在BeforeEach方法中給參數(shù),返回值設(shè)置值 然后在test方法中設(shè)置被測試的方法 二:可以檢測dao層sql的單元測試

    2024年02月15日
    瀏覽(19)
  • Go 單元測試之mock接口測試

    Go 單元測試之mock接口測試

    目錄 一、gomock 工具介紹 二、安裝 三、使用 3.1 指定三個參數(shù) 3.2 使用命令為接口生成 mock 實現(xiàn) 3.3 使用make 命令封裝處理mock 四、接口單元測試步驟 三、小黃書Service層單元測試 四、flags 五、打樁(stub) 參數(shù) 六、總結(jié) 6.1 測試用例定義 6.2 設(shè)計測試用例 6.3 執(zhí)行測試用例代碼

    2024年04月22日
    瀏覽(25)
  • Go語言測試——【單元測試 | Mock測試 | 基準測試】

    Go語言測試——【單元測試 | Mock測試 | 基準測試】

    作者 :非妃是公主 專欄 :《Golang》 博客主頁 :https://blog.csdn.net/myf_666 個性簽:順境不惰,逆境不餒,以心制境,萬事可成?!鴩?軟件測試 :軟件測試(英語:Software Testing),描述一種用來促進鑒定軟件的正確性、完整性、安全性和質(zhì)量的過程。換句話說,軟件測

    2024年02月10日
    瀏覽(22)
  • SpringBoot 使用Mock單元測試

    SpringBoot 使用Mock單元測試

    測試一般分為兩種黑盒測試和白盒測試。 ????????黑盒測試又稱為 功能測試 或 數(shù)據(jù)驅(qū)動測試 ,測試過程中,程序看作成一個黑色盒子,看不到盒子內(nèi)部代碼結(jié)構(gòu)。 ????????白盒測試又稱為 結(jié)構(gòu)測試 或 邏輯驅(qū)動測試 ,測試過程中,程序看作一個透明盒子,能夠看清

    2024年03月20日
    瀏覽(24)
  • 單元測試之Power Mock

    一、簡介 EasyMock、Mockito、jMock(單元測試模擬框架) 在有這些模擬框架之前,程序員為了編寫某一個函數(shù)的單元測試,必須進行十分繁瑣的初始化工作,以確保調(diào)用的接口或編寫的代碼得到預(yù)期的結(jié)果。單元測試模擬框架極大的簡化了單元測試的編寫過程,在被測試代碼需要

    2023年04月08日
    瀏覽(17)
  • CompletableFuture的單元測試Mock

    CompletableFuture的單元測試Mock

    在spring項目,假設(shè)我們有一個方法 我們對這個方法單元測試,大概率就直接寫成: 這樣會導(dǎo)致Completable的線程不運行,一直阻塞在紅色箭頭指示的地方: 等待線程執(zhí)行完畢。然而線程并沒有執(zhí)行。 此時需要模擬并驅(qū)動異步線程的執(zhí)行,因此需要這樣寫: 這樣就mock了對Runn

    2024年02月09日
    瀏覽(27)
  • java單元測試( Hamcrest 斷言)

    java單元測試( Hamcrest 斷言)

    單元測試特征: 1 范圍狹窄 2 限于單一類或方法 3 體積小 為什么要編寫單元測試? 為了防止錯誤(很明顯?。?而且還可以提高開發(fā)人員的生產(chǎn)力,因為單元測試: (1) 幫助實施——在編碼的同時編寫測試可以快速反饋正在編寫的代碼。 (2) 失敗時應(yīng)該易于理解——每個測試在

    2024年02月06日
    瀏覽(27)
  • SpringBoot單元測試斷言 assertions

    SpringBoot單元測試斷言 assertions

    斷言(assertions)是測試方法中的核心部分,用來對測試需要滿足的條件進行驗證。這些斷言方法都是 org.junit.jupiter.api.Assertions 的靜態(tài)方法。JUnit 5 內(nèi)置的斷言可以分成如下幾個類別: 1、簡單斷言 2、數(shù)組斷言 通過 assertArrayEquals 方法來判斷兩個對象或原始類型的數(shù)組是否相等

    2024年02月05日
    瀏覽(31)
  • JUnit 5單元測試(二)—— 斷言

    JUnit 5單元測試(二)—— 斷言

    上一篇講了 JUnit 5單元測試(一)—— 基本配置,書接上文開始 JUnit 5單元測試(二)—— 斷言 1.單元測試的類名應(yīng)該起為 xxxxTest.java 表明這個一個測試類,類名應(yīng)該用簡潔的英文表明測試內(nèi)容或函數(shù)。 例如:為了測試一個計算和的方法,可以取名為 SumTest.java 2.測試方法上

    2024年01月16日
    瀏覽(16)
  • 單元測試之Stub和Mock

    單元測試之Stub和Mock

    Analyze類會檢查filename的長度,如果小于8,我們就會使用一個實現(xiàn)IWebService的類來記錄錯誤. 我們需要給Analyze方法寫單元測試。 如果你想學(xué)習(xí)性能測試,我這邊給你推薦一套視頻,這個視頻可以說是B站播放全網(wǎng)第一的自動化測試教程,同時在線人數(shù)到達1000人,并且還有筆記可

    2024年01月17日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包