首頁 > 後端開發 > Golang > 主體

gomock 為除主方法中的第一個之外的所有子方法提供缺少的調用

WBOY
發布: 2024-02-08 22:18:09
轉載
1083 人瀏覽過

gomock 为除主方法中的第一个之外的所有子方法提供缺少的调用

php小編草莓為您介紹gomock,它是一個強大的測試工具,可以為主方法中的除第一個之外的所有子方法提供缺少的呼叫。這意味著,您可以使用gomock來模擬子方法的行為,從而更好地測試主方法的功能。 gomock的使用非常簡單,可以輕鬆建立和配置模擬對象,並設定預期的呼叫和返回值。無論您是在單元測試還是整合測試中,gomock都能幫助您更好地進行測試和驗證。無論您是初學者還是有經驗的開發者,gomock都是一個值得探索和使用的優秀工具。

問題內容

我有一個 go 方法,負責向使用者發送 OTP 訊息。它呼叫內部的四個方法(我說的是子方法)RemoveOTPGetOneTimePassCodeSaveOTPSendOTP

檔名:user_usecase.go

#
func (u *UserUseCase) SendUserOTP(ctx context.Context, user *domain.User, mobileNumber string) error {
    var err error
    var OTPNumber string
    var expiration time.Time
    //Remove previous OTP if any in DB
    if err = u.Repo.RemoveOTP(ctx, user.ID, mobileNumber); err != nil {
        return err
    }

    //Generate OTP
    OTPNumber, expiration, err = u.TokenService.GetOneTimePassCode()
    if err != nil {
        return err
    }

    //Save Code in Database and then send
    otpDataInput := domain.UserMobileOtps{
        UserID:       user.ID,
        MobileNumber: mobileNumber,
        Email:        user.Email,
        OtpCode:      OTPNumber,
        ExpiredAt:    expiration,
    }
    if err = u.Repo.SaveOTP(ctx, otpDataInput); err != nil {
        return err
    }

    if err = u.SMSService.SendOTP(ctx, mobileNumber, OTPNumber); err != nil {
        return err
    }
    return nil
}
登入後複製

測試案例檔案:user_usecase_test.go 和單元測試用例錯誤方法

// setup initializes common variables and returns them.
func setup(t *testing.T) (context.Context,
    *gomock.Controller,
    *mocks.MockUserRepository,
    usecase.UserUseCase,
    domain.User,
    *mocks.MockTokenService,
    *mocks.MockSMSService,
) {
    ctx := context.Background()
    ctrl := gomock.NewController(t)
    mockRepo := mocks.NewMockUserRepository(ctrl)
    mockTokenService := mocks.NewMockTokenService(ctrl)
    mockSmsService := mocks.NewMockSMSService(ctrl)
    uc := usecase.UserUseCase{Repo: mockRepo, TokenService: mockTokenService, SMSService: mockSmsService}
    user := domain.User{ID: 1}

    return ctx, ctrl, mockRepo, uc, user, mockTokenService, mockSmsService
}


func TestSendUserOTP_Error(t *testing.T) {
    ctx, ctrl, mockRepo, uc, user, mockTokenService, mockSmsService := setup(t)
    otpExpiration := time.Now().Add(time.Minute * 5)
    defer ctrl.Finish()

    someError := errors.New("some issue")
    mockRepo.EXPECT().RemoveOTP(ctx, user.ID, "XXXXXYYYYY").Return(someError).Times(1)
    mockTokenService.EXPECT().GetOneTimePassCode().Return("XXXYYY", otpExpiration, someError).Times(1)
    mockRepo.EXPECT().SaveOTP(ctx, domain.UserMobileOtps{UserID: user.ID, MobileNumber: "XXXXXYYYYY", Email: user.Email, OtpCode: "XXXYYY", ExpiredAt: otpExpiration}).Return(someError).Times(1)
    mockSmsService.EXPECT().SendOTP(ctx, "XXXXXYYYYY", "XXXYYY").Return(someError).Times(1)

    err := uc.SendVerificationOTP(ctx, &user, "XXXXXYYYYY")
    assert.Error(t, err)
    assert.Equal(t, someError, err)
}
登入後複製

現在在執行測試案例時,它不會為RemoveOTP拋出任何錯誤,但給出了其餘的三個方法。這是確切的錯誤

TestSendUserOTP_Error
    controller.go:310: missing call(s) to *mocks.MockTokenService.GetOneTimePassCode() /project_path/user/usecase/user_usecase_test.go
    
    controller.go:310: missing call(s) to *mocks.MockUserRepository.SaveOTP(is equal to context.Background (*context.emptyCtx), is equal to {{0 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {0001-01-01 00:00:00 +0000 UTC false}} 0 4 XXXXXYYYYY  XXXYYY 0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {2023-10-06 10:34:25.951558924 +0530 IST m=+600.001514851 true} {0001-01-01 00:00:00 +0000 UTC false}} /project_path/user/usecase/user_usecase_test.go
  
    controller.go:310: missing call(s) to *mocks.MockSMSService.SendOTP(is equal to context.Background (*context.emptyCtx), is equal to XXXXXYYYYY (string), is equal to XXXYYY (string)) /project_path/user/usecase/user_usecase_test.go
    
    controller.go:310: aborting test due to missing call(s)
--- FAIL: TestSendUserOTP_Error (0.00s)
登入後複製

我不想使用像 AnyTimes() 這樣的解決方案,因為我確信所有子方法都會被呼叫一次。對此的理想解決方案應該是什麼?請提出建議。

解決方法

問題是您的RemoveOTP()函數傳回錯誤,因此您的程式碼不會執行任何其他方法。 (如名稱所示,未接來電)

給 AnyTimes() 使其運行成功,因為它可以運行 0 次到多次。

如果你真的想測試所有方法都執行一次,也許你可以模擬所有函數不回傳錯誤,以便它執行你的所有程式碼

以上是gomock 為除主方法中的第一個之外的所有子方法提供缺少的調用的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!