-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Description
Hi
It took us a while to find this really easy to use pattern for table driven tests with mocks.
The idea is that each test contains a prepare function that gets the mock objects and runs the test case logic.
Before that, we had lots of if statements in the test itself, and here we moved the logic to the table so it is much easier to read and understand.
Here it is, and I suggest maybe add it to the docs/readme?
func TestUnit_Func1(t *testing.T) {
t.Parallel()
tests = []struct{
name string // name for test case
arg1 string
arg2 int
want *Result
wantError bool
prepare func(*client1.Mock, *client2.Mock)
}{
{
// test 1
name: "simple input",
arg1: "a",
arg2: 1,
want: &Result{Concat: "a1"},
wantErr: false,
prepare: func(c1 *client1.Mock, c2 *client2.Mock) {
// here we prepare the mocks that the unit are dependent on.
c1.On("Check", mock.Anything).Return(nil).Once()
c2.On("Add", "a", 1).Return("a1", nil).Once()
// ...
},
},
{
// test 2
},
// ...
}
for _, tt := range tests {
// constract a unique name for the test, from the function arguments
name := fmt.Sprintf("%s,%d", tt.arg1, tt.arg2)
tt := tt
// run a sub-test:
t.Run(name, func(t *testing.T) {
t.Parallel()
// create mocks
c1 := new(client1.Mock)
c2 := new(client2.Mock)
// prepare the mocks:
if tt.prepare != nil {
tt.prepare(c1, c2)
}
// create unit
u, err := New(c1, c2)
require.Nil(t, err)
// run the tested function
got, err := u.Func1(tt.arg1, tt.arg2)
// assert results expectations
if tt.wantErr {
assert.NotNil(t, err)
} else {
assert.Nil(t, err)
assert.Equal(t, want, got) // notice the go convention: want is first argument, got is the second argument
}
// assert that the mocks were called correctly.
c1.AssertExpectations(t)
c2.AssertExpectations(t)
})
}
}Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels