php小編草莓為您介紹gomock,它是一個強大的測試工具,可以為主方法中的除第一個之外的所有子方法提供缺少的呼叫。這意味著,您可以使用gomock來模擬子方法的行為,從而更好地測試主方法的功能。 gomock的使用非常簡單,可以輕鬆建立和配置模擬對象,並設定預期的呼叫和返回值。無論您是在單元測試還是整合測試中,gomock都能幫助您更好地進行測試和驗證。無論您是初學者還是有經驗的開發者,gomock都是一個值得探索和使用的優秀工具。
我有一個 go 方法,負責向使用者發送 OTP 訊息。它呼叫內部的四個方法(我說的是子方法)RemoveOTP、GetOneTimePassCode、SaveOTP和SendOTP。
檔名: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中文網其他相關文章!