我有一個user service驗證用戶資料并格式化它,然后呼叫 Firebase 服務,該服務創建一個 firebase 用戶并回傳 firebase id,然后將該用戶資料傳遞給repository層。我的用戶結構已一個ID場由填充uuid在user service 傳遞到前repository層。我正在使用strecher/testify. 但是測驗失敗了,因為它ID是由服務層填充的,我無法將它傳遞ID給模擬函式使用的用戶資料。
user := model.User{
ID: "",
FirebaseID: "",
FirstName: "Test",
LastName: "User",
FullName: "Test User",
Email: "[email protected]"
Password: "password",
}
服務層代碼
func (u userService) CreateUser(user model.User) error {
err := validateFields(user)
if err != nil {
return fmt.Errorf("userService CreateUser: %w", err)
}
user.FullName = user.FirstName " " user.LastName
user.FirebaseID, err = u.authClient.CreateUser(user)
if err != nil {
return fmt.Errorf("userService CreateUser: %w", err)
}
user.ID = uuid.NewString()
err = u.userRepo.CreateUser(user)
if err != nil {
return fmt.Errorf("userService CreateUser: %w", err)
}
return nil
}
測驗代碼
func TestCreateUser(t *testing.T) {
mockFirebaseAuthClient := new(MockFirebaseAuthClient)
mockPostgresRepo := new(MockPostgresRepo)
userService := NewUserService(mockPostgresRepo, mockFirebaseAuthClient)
t.Run("Valid data", func(t *testing.T) {
user := model.User{
ID: "",
FirebaseID: "firebaseuniqueid",
FirstName: "Test",
LastName: "User",
FullName: "Test User",
Email: "[email protected]",
Password: "password",
}
mockFirebaseAuthClient.On("CreateUser", user).Return("firebaseuniqueid", nil)
mockPostgresRepo.On("CreateUser", user).Return(nil)
err := userService.CreateUser(user)
if err != nil {
t.Fatalf("Expectd: nil, got: %v", err)
}
})
測驗時出錯
mock: Unexpected Method Call
-----------------------------
CreateUser(model.User)
0: model.User{ID:"f87fd2f3-5801-4359-a565-a4eb13a6de37", FirebaseID:"firebaseuniqueid", FirstName:"Test", LastName:"User", FullName:"Test User", Email:"[email protected]", Password:"password"}
The closest call I have is:
CreateUser(model.User)
0: model.User{ID:"", FirebaseID:"firebaseuniqueid", FirstName:"Test", LastName:"User", FullName:"Test User", Email:"[email protected]", Password:"password"}
Difference found in argument 0:
--- Expected
Actual
@@ -1,3 1,3 @@
(model.User) {
- ID: (string) "",
ID: (string) (len=36) "f87fd2f3-5801-4359-a565-a4eb13a6de37",
FirebaseID: (string) (len=16) "firebaseuniqueid",
Diff: 0: FAIL: (model.User={f87fd2f3-5801-4359-a565-a4eb13a6de37 firebaseuniqueid Test User Test User [email protected] password}) != (model.User={ firebaseuniqueid Test User Test User [email protected] password}) [recovered]
有什么方法可以檢查動態創建的 uuid 或忽略測驗中結構中的值嗎?
uj5u.com熱心網友回復:
如果您不想考慮mockFirebaseAuthClient.On("CreateUser", user).Return("firebaseuniqueid", nil)并且mockPostgresRepo.On("CreateUser", user).Return(nil)只想模擬該呼叫,那么您可以mock.Anything在兩個呼叫中使用作為引數,而不是user像這樣mockFirebaseAuthClient.On("CreateUser", mock.Anything).Return("firebaseuniqueid", nil)。因此不會考慮引數,模擬呼叫將回傳所需的值。
uj5u.com熱心網友回復:
關于你的問題
既然uuid沒有注入到service層,那怎么mock呢?它是一個進口包。
像這樣,首先,定義一個與我們要模擬的方法相同的介面
type uuidGen interface {
String() string
}
然后,定義一個模擬型別,我們將在其中定義我們的方法
type mockGen struct{}
然后,在型別上定義方法
func (u *mockGen) String() string {
return "test"
}
更新CreateUser函式以接收與的包uuidGen共享方法的引數。String()uuid
func (u userService) CreateUser(uuid uuidGen, user User) error {
err := validateFields(user)
if err != nil {
return fmt.Errorf("userService CreateUser: %w", err)
}
user.FullName = user.FirstName " " user.LastName
user.FirebaseID, err = u.authClient.CreateUser(user)
if err != nil {
return fmt.Errorf("authClient CreateUser: %w", err)
}
user.ID = uuid.String()
err = u.userRepo.CreateUser(user)
if err != nil {
return fmt.Errorf("userService CreateUser: %w", err)
}
return nil
}
現在我們可以這樣寫測驗了,看看這2個方法是如何接受實作介面的不同型別uuidGen并且可以呼叫一個方法的String()
func TestCreateUser(t *testing.T) {
mockFirebaseAuthClient := new(MockFirebaseAuthClient)
mockPostgresRepo := new(MockPostgresRepo)
userService := NewUserService("test", "test")
t.Run("Valid data", func(t *testing.T) {
user := User{
ID: "",
FirebaseID: "firebaseuniqueid",
FirstName: "Test",
LastName: "User",
FullName: "Test User",
Email: "[email protected]",
Password: "password",
}
mockFirebaseAuthClient.On("CreateUser", user).Return("firebaseuniqueid", nil)
mockPostgresRepo.On("CreateUser", user).Return(nil)
gen := new(mockGen)
err := userService.CreateUser(gen, user)
if err != nil {
t.Fatalf("Expectd: nil, got: %v", err)
}
realUUID := uuid.New()
err = userService.CreateUser(realUUID, user)
if err != nil {
t.Fatalf("Expectd: nil, got: %v", err)
}
t.Log("Mock UUID:", gen.String()) // prints test
t.Log("Real UUID UUID:", realUUID.String()) // prints a UUID
})
}
運行它go test -v以查看輸出t.Log(...)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/386937.html
