-
Notifications
You must be signed in to change notification settings - Fork 103
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor(ecocredit): GetParamSet
-> Get
#1064
Conversation
Codecov Report
@@ Coverage Diff @@
## master #1064 +/- ##
==========================================
- Coverage 68.10% 68.00% -0.10%
==========================================
Files 210 207 -3
Lines 20968 20855 -113
==========================================
- Hits 14280 14183 -97
+ Misses 5375 5367 -8
+ Partials 1313 1305 -8
Flags with carried forward coverage won't be shown. Click here to find out more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple concerns, one with using panic and another with abstracting the expect calls.
minFee := sdk.NewCoins(sdk.NewCoin("regen", sdk.NewInt(100))) | ||
|
||
// no fee specified should fail | ||
gmAny := gomock.Any() | ||
s.paramsKeeper.EXPECT().GetParamSet(gmAny, gmAny).Do(func(any interface{}, p *core.Params) { | ||
p.BasketFee = minFee | ||
}).Times(2) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure we should abstract the expect call. If anything, we should be more specific with the values passed and avoid using gomock.Any()
whenever possible. This looks like a nice improvement but I think we lose some of the value of using mocks. I realize the abstracted method currently provides the same assurance as what was before but if we want to be more specific, we should use the expect call directly.
// ExpectParamGet is a helper function that sets up an expected mock call for the provided type. | ||
// Once we switch to Go 1.18+ we can switch this impl to be generic: | ||
// func ExpectParamGet[T any](obj *T, paramKeeper *mocks.MockParamKeeper, times int) { | ||
// gmAny := gomock.Any() | ||
// paramKeeper.EXPECT().Get(gmAny, gmAny, gmAny).Do(func(_, _ any, param *T) { | ||
// *param = *obj | ||
// }).Times(times) | ||
// } | ||
func ExpectParamGet(obj interface{}, paramKeeper *mocks.MockParamKeeper, times int) { | ||
gmAny := gomock.Any() | ||
switch obj.(type) { | ||
case *[]string: | ||
s := obj.(*[]string) | ||
paramKeeper.EXPECT().Get(gmAny, gmAny, gmAny).Do(func(_, _ interface{}, param *[]string) { | ||
*param = *s | ||
}).Times(times) | ||
case *sdk.Coins: | ||
coins := obj.(*sdk.Coins) | ||
paramKeeper.EXPECT().Get(gmAny, gmAny, gmAny).Do(func(_, _ interface{}, param *sdk.Coins) { | ||
*param = *coins | ||
}).Times(times) | ||
case *bool: | ||
b := obj.(*bool) | ||
paramKeeper.EXPECT().Get(gmAny, gmAny, gmAny).Do(func(_, _ interface{}, param *bool) { | ||
*param = *b | ||
}).Times(times) | ||
case *[]*core.AskDenom: | ||
askDenoms := obj.(*[]*core.AskDenom) | ||
paramKeeper.EXPECT().Get(gmAny, gmAny, gmAny).Do(func(_, _ interface{}, param *[]*core.AskDenom) { | ||
*param = *askDenoms | ||
}).Times(times) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should abstract the expect call. We should try to avoid using gomock.Any()
and be more specific with the values passed whenever possible. This may be convenient but gomock.Any()
should be used sparingly and we should be as specific as we can when we can when writing tests.
For example, I started using specific values with expect calls in the acceptance tests I'm currently drafting:
regen-ledger/x/ecocredit/server/basket/msg_put_test.go
Lines 335 to 341 in bf21ecc
s.bankKeeper.EXPECT(). | |
MintCoins(s.sdkCtx, basket.BasketSubModuleName, coins). | |
Return(nil).AnyTimes() | |
s.bankKeeper.EXPECT(). | |
SendCoinsFromModuleToAccount(s.sdkCtx, basket.BasketSubModuleName, s.addr, coins). | |
Return(nil).AnyTimes() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this method is specific to params (ExpectParamGet
). the only more specific i can really get is the param key ( and maybe the context, but incorrect contexts would be caught by compiler anyway). i can go ahead and add key []byte
as an argument
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ryanchristo i think you may have missed this reply 👋🏻
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the only more specific i can really get is the param key
Nope. I saw it. We don't need to use gomock.Any()
. See #1064 (comment).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we should be adding more parameters. Might as well use the expect call directly if we add any more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might as well use the expect call directly if we add any more.
it's only 4 params, i'd much prefer that over the 4+ lines from direct expect call. the only thing thats different at this point is the expected context, but i dont really see that as necessary or valuable, as its not used, and the app wont even compile if we pass anything other than sdk.Context to the acutal params.Get
call in the keeper methods.
@aleem1314 could i get a review here 🙏🏻 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still not sure about abstracting the expect call and think we should be as specific as possible when writing tests. I included a working example without using gomock.Any()
.
s.paramsKeeper.EXPECT().GetParamSet(gmAny, gmAny).Do(func(any interface{}, p *core.Params) { | ||
p.BasketFee = fee | ||
}).Times(1) | ||
utils.ExpectParamGet(&basketFees, s.paramsKeeper, core.KeyBasketCreationFee, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here's a working example without using gomock.Any()
and using a specific time:
utils.ExpectParamGet(&basketFees, s.paramsKeeper, core.KeyBasketCreationFee, 1) | |
var coins sdk.Coins | |
s.paramsKeeper.EXPECT().Get(s.sdkCtx, core.KeyBasketCreationFee, &coins). | |
Do(func(ctx sdk.Context, key []byte, ptr *sdk.Coins) { | |
ptr = &basketFees | |
}). | |
Times(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if setting the ptr is necessary because it works without it and regardless of what it gets set too, in which case it could be:
utils.ExpectParamGet(&basketFees, s.paramsKeeper, core.KeyBasketCreationFee, 1) | |
var coins sdk.Coins | |
s.paramsKeeper.EXPECT().Get(s.sdkCtx, core.KeyBasketCreationFee, &coins). | |
Do(func(sdk.Context, []byte, *sdk.Coins) {}). | |
Times(1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
Description
Closes: #996
Get
Author Checklist
All items are required. Please add a note to the item if the item is not applicable and
please add links to any relevant follow up issues.
I have...
!
to the type prefix if API or client breaking changeCHANGELOG.md
Reviewers Checklist
All items are required. Please add a note if the item is not applicable and please add
your handle next to the items reviewed if you only reviewed selected items.
I have...
!
in the type prefix if API or client breaking change