Ask: "Generate comprehensive table-driven tests with:
func TestUserService_GetUser ( t * testing . T ) {
mockSetup func ( * mocks . UserRepository , * mocks . Cache )
name: "success from cache" ,
mockSetup: func ( repo * mocks . UserRepository , cache * mocks . Cache ) {
cache. On ( "Get" , mock.Anything, "user:123" ).
Return ( & User {ID: "123" , Name: "John" }, nil )
want: & User {ID: "123" , Name: "John" },
name: "success from database" ,
mockSetup: func ( repo * mocks . UserRepository , cache * mocks . Cache ) {
cache. On ( "Get" , mock.Anything, "user:456" ).
Return ( nil , errors. New ( "not found" ))
repo. On ( "FindByID" , mock.Anything, "456" ).
Return ( & User {ID: "456" , Name: "Jane" }, nil )
cache. On ( "Set" , mock.Anything, "user:456" ,
mock.Anything, 5 * time.Minute). Return ( nil )
want: & User {ID: "456" , Name: "Jane" },
mockSetup: func ( repo * mocks . UserRepository , cache * mocks . Cache ) {
cache. On ( "Get" , mock.Anything, "user:999" ).
Return ( nil , errors. New ( "not found" ))
repo. On ( "FindByID" , mock.Anything, "999" ).
for _, tt := range tests {
t. Run (tt.name, func ( t * testing . T ) {
repo := new ( mocks . UserRepository )
cache := new ( mocks . Cache )
logger, _ := zap. NewDevelopment ()
tt. mockSetup (repo, cache)
svc := NewUserService (repo, cache, logger)
got, err := svc. GetUser (context. Background (), tt.userID)
assert. ErrorIs (t, err, tt.wantErr)
assert. Equal (t, tt.want, got)
repo. AssertExpectations (t)
cache. AssertExpectations (t)