Convert the git package into functions that can be mocked with go-mock
Idea:
To make git related things easier to add and test, the GitLab CLI is going to use gomock for our git library functions.
We'll do this in 3 steps:
- Create all new functions that can be mocked, in a separate library file
- Replace functions in the
gitlibrary with the new [mockable] functions.- This is a good opportunity to clean these up. There could be some functions that can be refactored to be cleaner/simpler.
- We should make sure there are adequate tests for all these as well.
- When one function is completely replaced, remove the old one and move it to the
gitmodule.
Examples:
We have a function called git.Backflip.
- Create a new function
git_mock.Backflipthat is part of theStandardGitRunnerinterface:
func (g *StandardGitRunner) Backflip(branch string) error {
_, stderr, err := g.runGitCommand("do-a-backflip", branch)
if err != nil {
return fmt.Errorf("could not sufficiently backflip: %v - %s", err, stderr)
}
return nil
}
- Create a test for
git_mock.Backflip:
func TestBackflip(t *testing.T) {
tests := []struct {
name string
branch string
setupMock func(*MockGitInterface, string)
expectedError error
}{
{
name: "successful backflip",
branch: "backflipbranch",
setupMock: func(m *MockGitInterface, branch string) {
m.EXPECT().Backflip(branch).Return(nil)
},
expectedError: nil,
},
{
name: "branch checkout fails",
branch: "faklsdjflkawjef",
setupMock: func(m *MockGitInterface, branch string) {
m.EXPECT().CheckoutBranch(branch).Return(errors.New("could not checkout branch"))
},
expectedError: errors.New("could not checkout branch"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockGit := NewMockGitInterface(ctrl)
tt.setupMock(mockGit, tt.branch)
err := mockGit.CheckoutBranch(tt.branch)
if tt.expectedError != nil {
require.Error(t, err)
require.Equal(t, tt.expectedError.Error(), err.Error())
} else {
require.NoError(t, err)
}
})
}
}
- Replace
git.Backflipwithgit_interface.Backflipin the code. (and make sure everything is working!)
diff --git a/backfip_cmd.go b/backfip_cmd.go
index 3ac17f4c32c2..2c46ee8fc772 100644
--- a/backfip_cmd.go
+++ b/backfip_cmd.go
@@ -1,7 +1,7 @@
import "fmt"
func DoABackflip(branch string) error {
- err := git.Backflip(branch)
+ err := git_interface.Backflip(branch)
if err != nil {
return fmt.Errorf("something went wrong with the backflip: %v", stderr)
}
Notes:
Doesn't this make git based commands subject to errors if git changes syntax?
It does, good thinking! That's why we'll include an integration test layer that actually tests these commands are getting (something close to) the output and results we expect.
Where was this discussed?
Please check the thread in !1945 (comment 2389898291)