refactor: use mocks for x/auth/vesting module unit tests (#13127)

* add msg_server test for x/auth/vesting

* Update msg_server_test.go

* Update x/auth/vesting/msg_server_test.go

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

* Update x/auth/vesting/msg_server_test.go

Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>

Co-authored-by: Marko <marbar3778@yahoo.com>
Co-authored-by: Aleksandr Bezobchuk <alexanderbez@users.noreply.github.com>
This commit is contained in:
cool-developer 2022-09-01 22:10:52 -07:00 committed by GitHub
parent 9948fb6c7c
commit dd556936b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 339 additions and 4 deletions

View File

@ -73,7 +73,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
* [#13048](https://github.com/cosmos/cosmos-sdk/pull/13048) Add handling of AccountNumberStoreKeyPrefix to the x/auth simulation decoder.
* [#13101](https://github.com/cosmos/cosmos-sdk/pull/13101) Remove weights from `simapp/params` and `testutil/sims`. They are now in their respective modules.
* (simapp) [#13107](https://github.com/cosmos/cosmos-sdk/pull/13107) Call `SetIAVLCacheSize` with the configured value in simapp.
* [#12398](https://github.com/cosmos/cosmos-sdk/issues/12398) Refactor all `x` modules to unit-test via mocks and decouple `simapp`.
### State Machine Breaking

View File

@ -26,3 +26,4 @@ $mockgen_cmd -source=x/slashing/types/expected_keepers.go -package testutil -des
$mockgen_cmd -source=x/genutil/types/expected_keepers.go -package testutil -destination x/genutil/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/gov/testutil/expected_keepers.go -package testutil -destination x/gov/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/staking/types/expected_keepers.go -package testutil -destination x/staking/testutil/expected_keepers_mocks.go
$mockgen_cmd -source=x/auth/vesting/types/expected_keepers.go -package testutil -destination x/auth/vesting/testutil/expected_keepers_mocks.go

View File

@ -10,11 +10,10 @@ import (
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/testutil/network"
testutil2 "github.com/cosmos/cosmos-sdk/x/auth/vesting/client/testutil"
)
func TestIntegrationTestSuite(t *testing.T) {
cfg := network.DefaultConfig(simapp.NewTestNetworkFixture)
cfg.NumValidators = 1
suite.Run(t, testutil2.NewIntegrationTestSuite(cfg))
suite.Run(t, NewIntegrationTestSuite(cfg))
}

View File

@ -0,0 +1,254 @@
package vesting_test
import (
"testing"
"time"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/suite"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmtime "github.com/tendermint/tendermint/types/time"
sdk "github.com/cosmos/cosmos-sdk/types"
authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
"github.com/cosmos/cosmos-sdk/x/auth/vesting"
"github.com/cosmos/cosmos-sdk/testutil"
moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
vestingtestutil "github.com/cosmos/cosmos-sdk/x/auth/vesting/testutil"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
vestingtypes "github.com/cosmos/cosmos-sdk/x/auth/vesting/types"
)
var (
fromAddr = sdk.AccAddress([]byte("from1________________"))
to1Addr = sdk.AccAddress([]byte("to1__________________"))
to2Addr = sdk.AccAddress([]byte("to2__________________"))
to3Addr = sdk.AccAddress([]byte("to3__________________"))
fooCoin = sdk.NewInt64Coin("foo", 100)
periodCoin = sdk.NewInt64Coin("foo", 20)
)
type VestingTestSuite struct {
suite.Suite
ctx sdk.Context
accountKeeper authkeeper.AccountKeeper
bankKeeper *vestingtestutil.MockBankKeeper
msgServer vestingtypes.MsgServer
}
func (s *VestingTestSuite) SetupTest() {
key := sdk.NewKVStoreKey(authtypes.StoreKey)
testCtx := testutil.DefaultContextWithDB(s.T(), key, sdk.NewTransientStoreKey("transient_test"))
s.ctx = testCtx.Ctx.WithBlockHeader(tmproto.Header{Time: tmtime.Now()})
encCfg := moduletestutil.MakeTestEncodingConfig()
maccPerms := map[string][]string{}
ctrl := gomock.NewController(s.T())
s.bankKeeper = vestingtestutil.NewMockBankKeeper(ctrl)
s.accountKeeper = authkeeper.NewAccountKeeper(
encCfg.Codec,
key,
authtypes.ProtoBaseAccount,
maccPerms,
"cosmos",
authtypes.NewModuleAddress("gov").String(),
)
vestingtypes.RegisterInterfaces(encCfg.InterfaceRegistry)
authtypes.RegisterInterfaces(encCfg.InterfaceRegistry)
s.msgServer = vesting.NewMsgServerImpl(s.accountKeeper, s.bankKeeper)
}
func (s *VestingTestSuite) TestCreateVestingAccount() {
testCases := map[string]struct {
preRun func()
input *vestingtypes.MsgCreateVestingAccount
expErr bool
expErrMsg string
}{
"create for existing account": {
preRun: func() {
toAcc := s.accountKeeper.NewAccountWithAddress(s.ctx, to1Addr)
s.bankKeeper.EXPECT().IsSendEnabledCoins(gomock.Any(), fooCoin).Return(nil)
s.accountKeeper.SetAccount(s.ctx, toAcc)
s.bankKeeper.EXPECT().BlockedAddr(to1Addr).Return(false)
},
input: vestingtypes.NewMsgCreateVestingAccount(
fromAddr,
to1Addr,
sdk.Coins{fooCoin},
time.Now().Unix(),
true,
),
expErr: true,
expErrMsg: "already exists",
},
"create a valid delayed vesting account": {
preRun: func() {
s.bankKeeper.EXPECT().IsSendEnabledCoins(gomock.Any(), fooCoin).Return(nil)
s.bankKeeper.EXPECT().BlockedAddr(to2Addr).Return(false)
s.bankKeeper.EXPECT().SendCoins(gomock.Any(), fromAddr, to2Addr, sdk.Coins{fooCoin}).Return(nil)
},
input: vestingtypes.NewMsgCreateVestingAccount(
fromAddr,
to2Addr,
sdk.Coins{fooCoin},
time.Now().Unix(),
true,
),
expErr: false,
expErrMsg: "",
},
"create a valid continuous vesting account": {
preRun: func() {
s.bankKeeper.EXPECT().IsSendEnabledCoins(gomock.Any(), fooCoin).Return(nil)
s.bankKeeper.EXPECT().BlockedAddr(to3Addr).Return(false)
s.bankKeeper.EXPECT().SendCoins(gomock.Any(), fromAddr, to3Addr, sdk.Coins{fooCoin}).Return(nil)
},
input: vestingtypes.NewMsgCreateVestingAccount(
fromAddr,
to3Addr,
sdk.Coins{fooCoin},
time.Now().Unix(),
false,
),
expErr: false,
expErrMsg: "",
},
}
for name, tc := range testCases {
s.Run(name, func() {
tc.preRun()
_, err := s.msgServer.CreateVestingAccount(s.ctx, tc.input)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)
}
})
}
}
func (s *VestingTestSuite) TestCreatePermanentLockedAccount() {
testCases := map[string]struct {
preRun func()
input *vestingtypes.MsgCreatePermanentLockedAccount
expErr bool
expErrMsg string
}{
"create for existing account": {
preRun: func() {
toAcc := s.accountKeeper.NewAccountWithAddress(s.ctx, to1Addr)
s.bankKeeper.EXPECT().IsSendEnabledCoins(gomock.Any(), fooCoin).Return(nil)
s.bankKeeper.EXPECT().BlockedAddr(to1Addr).Return(false)
s.accountKeeper.SetAccount(s.ctx, toAcc)
},
input: vestingtypes.NewMsgCreatePermanentLockedAccount(
fromAddr,
to1Addr,
sdk.Coins{fooCoin},
),
expErr: true,
expErrMsg: "already exists",
},
"create a valid permanent locked account": {
preRun: func() {
s.bankKeeper.EXPECT().IsSendEnabledCoins(gomock.Any(), fooCoin).Return(nil)
s.bankKeeper.EXPECT().BlockedAddr(to2Addr).Return(false)
s.bankKeeper.EXPECT().SendCoins(gomock.Any(), fromAddr, to2Addr, sdk.Coins{fooCoin}).Return(nil)
},
input: vestingtypes.NewMsgCreatePermanentLockedAccount(
fromAddr,
to2Addr,
sdk.Coins{fooCoin},
),
expErr: false,
expErrMsg: "",
},
}
for name, tc := range testCases {
s.Run(name, func() {
tc.preRun()
_, err := s.msgServer.CreatePermanentLockedAccount(s.ctx, tc.input)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)
}
})
}
}
func (s *VestingTestSuite) TestCreatePeriodicVestingAccount() {
testCases := map[string]struct {
preRun func()
input *vestingtypes.MsgCreatePeriodicVestingAccount
expErr bool
expErrMsg string
}{
"create for existing account": {
preRun: func() {
toAcc := s.accountKeeper.NewAccountWithAddress(s.ctx, to1Addr)
s.accountKeeper.SetAccount(s.ctx, toAcc)
},
input: vestingtypes.NewMsgCreatePeriodicVestingAccount(
fromAddr,
to1Addr,
time.Now().Unix(),
[]vestingtypes.Period{
{
Length: 10,
Amount: sdk.NewCoins(periodCoin),
},
},
),
expErr: true,
expErrMsg: "already exists",
},
"create a valid periodic vesting account": {
preRun: func() {
s.bankKeeper.EXPECT().SendCoins(gomock.Any(), fromAddr, to2Addr, gomock.Any()).Return(nil)
},
input: vestingtypes.NewMsgCreatePeriodicVestingAccount(
fromAddr,
to2Addr,
time.Now().Unix(),
[]vestingtypes.Period{
{
Length: 10,
Amount: sdk.NewCoins(periodCoin),
},
{
Length: 20,
Amount: sdk.NewCoins(fooCoin),
},
},
),
expErr: false,
expErrMsg: "",
},
}
for name, tc := range testCases {
s.Run(name, func() {
tc.preRun()
_, err := s.msgServer.CreatePeriodicVestingAccount(s.ctx, tc.input)
if tc.expErr {
s.Require().Error(err)
s.Require().Contains(err.Error(), tc.expErrMsg)
} else {
s.Require().NoError(err)
}
})
}
}
func TestVestingTestSuite(t *testing.T) {
suite.Run(t, new(VestingTestSuite))
}

View File

@ -0,0 +1,82 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: x/auth/vesting/types/expected_keepers.go
// Package testutil is a generated GoMock package.
package testutil
import (
reflect "reflect"
types "github.com/cosmos/cosmos-sdk/types"
gomock "github.com/golang/mock/gomock"
)
// MockBankKeeper is a mock of BankKeeper interface.
type MockBankKeeper struct {
ctrl *gomock.Controller
recorder *MockBankKeeperMockRecorder
}
// MockBankKeeperMockRecorder is the mock recorder for MockBankKeeper.
type MockBankKeeperMockRecorder struct {
mock *MockBankKeeper
}
// NewMockBankKeeper creates a new mock instance.
func NewMockBankKeeper(ctrl *gomock.Controller) *MockBankKeeper {
mock := &MockBankKeeper{ctrl: ctrl}
mock.recorder = &MockBankKeeperMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use.
func (m *MockBankKeeper) EXPECT() *MockBankKeeperMockRecorder {
return m.recorder
}
// BlockedAddr mocks base method.
func (m *MockBankKeeper) BlockedAddr(addr types.AccAddress) bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "BlockedAddr", addr)
ret0, _ := ret[0].(bool)
return ret0
}
// BlockedAddr indicates an expected call of BlockedAddr.
func (mr *MockBankKeeperMockRecorder) BlockedAddr(addr interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BlockedAddr", reflect.TypeOf((*MockBankKeeper)(nil).BlockedAddr), addr)
}
// IsSendEnabledCoins mocks base method.
func (m *MockBankKeeper) IsSendEnabledCoins(ctx types.Context, coins ...types.Coin) error {
m.ctrl.T.Helper()
varargs := []interface{}{ctx}
for _, a := range coins {
varargs = append(varargs, a)
}
ret := m.ctrl.Call(m, "IsSendEnabledCoins", varargs...)
ret0, _ := ret[0].(error)
return ret0
}
// IsSendEnabledCoins indicates an expected call of IsSendEnabledCoins.
func (mr *MockBankKeeperMockRecorder) IsSendEnabledCoins(ctx interface{}, coins ...interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
varargs := append([]interface{}{ctx}, coins...)
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsSendEnabledCoins", reflect.TypeOf((*MockBankKeeper)(nil).IsSendEnabledCoins), varargs...)
}
// SendCoins mocks base method.
func (m *MockBankKeeper) SendCoins(ctx types.Context, fromAddr, toAddr types.AccAddress, amt types.Coins) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SendCoins", ctx, fromAddr, toAddr, amt)
ret0, _ := ret[0].(error)
return ret0
}
// SendCoins indicates an expected call of SendCoins.
func (mr *MockBankKeeperMockRecorder) SendCoins(ctx, fromAddr, toAddr, amt interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendCoins", reflect.TypeOf((*MockBankKeeper)(nil).SendCoins), ctx, fromAddr, toAddr, amt)
}

View File

@ -20,7 +20,6 @@ func TestItCreatesModuleAccountOnInitBlock(t *testing.T) {
ctx := app.BaseApp.NewContext(false, tmproto.Header{})
acc := accountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.BondedPoolName))
require.NotNil(t, acc)
acc = accountKeeper.GetAccount(ctx, authtypes.NewModuleAddress(types.NotBondedPoolName))