-
Notifications
You must be signed in to change notification settings - Fork 607
Running function lambda arguments #26
Description
Currently in our project, we have a function in our interface that accepts a lambda, does some logic (specifically, starts a database transaction), then runs the lambda in the context of that logic.
However, gomock doesn't have a way, as far as I've found, to run that lambda argument and then assert its behavior. I've hacked it a bit by replacing that function in the generated file with a simple command to run the argument in question and return its result, but it'd be nice if there was a built in way to do this without editing generated code.
I noticed that the Call type has a Do method which accepts a lambda (with a TODO to actually make sure it's a lambda), then calls it later down the line. Perhaps have a method on Call that, similar to SetArg, runs a particular argument in the same fashion Do does (example, CallArg(n int)
). This would let me assert behavior that happens in that lambda (which also utilizes the mock). May be complicated by the fact that the lambda in question (in my code) needs to have the mock _m
provided as an argument to it. Maybe CallArg(n int, args ...interface{})
to provide arguments for the call (which I could then feed the mock object to)?
Trimmed down example:
// persist.go
type Persister interface {
RunInTx(TxFunc) error
Foo()
Bar()
}
type TxFunc func(tx Persister) error
func (p persister) RunInTx(f TxFunc) error {
tx := p.StartTx()
return f(tx)
}
// main.go
func main() {
p := persist.NewPersister()
log.Printf(DoStuff(p))
}
func DoStuff(p persist.Persister) error {
return p.RunInTx(func(tx persist.Persister) error {
tx.Foo()
tx.Bar()
})
}
// main_test.go
func TestDoStuff(t *testing.T) {
mockCtrl := gomock.NewController(t)
mockPersist := mock_persist.NewPersist(mockCtrl)
// Currently these calls never happen, because the lambda in DoStuff is never run
mockPersist.EXPECT().Foo()
mockPersist.EXPECT().Bar()
DoStuff(mockPersist)
}
And the hacky way I've solved it for now, for reference:
func (_m *MockPersister) RunInTx(_param0 persist.TxFunc) error {
return _param0(_m)
//ret := _m.ctrl.Call(_m, "RunInTx", _param0)
//ret0, _ := ret[0].(error)
//return ret0
}