Skip to content

Commit

Permalink
sub test passed into assertion
Browse files Browse the repository at this point in the history
  • Loading branch information
jurabek committed Mar 13, 2021
1 parent b2181cd commit 2238690
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 12 deletions.
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ This repo shows how to test and mock multiple dependencies using table-driven te


## Problem
Sometimes you need to mock multiple dependencies for specific test cases, imagine we have a type `MacBook` and it depends on `CPU`, `GPU` and `RAM` and we have a `Diagnose` method that returns an error if some of the dependencies hit the threshold.

In unit testing and mocking world we need to mock multiple dependencies for specific test cases, (e.g) imagine we have a `struct MacBook` and it depends on `CPU`, `GPU` and `RAM` and we have a `Diagnose` method that returns an error if some of the dependencies `usage` property hits the threshold.
```
type MacBook struct {
cpu cpu.CPU
Expand All @@ -28,7 +27,7 @@ func (m *MacBook) Diagnose(cpuThreshold, gpuThreshold, memoryThreshold int) erro
return nil
}
```
as you can see we have 3 if condtions, to be able to test happy case that returns no error, we need to write at least 4 unit tests and mock all dependencies.
example above we have 3 if conditions, in order to test and get happy result that returns no error, we should have to write at least 4 unit tests or more and mock all dependencies.

## Solution
```
Expand Down Expand Up @@ -71,8 +70,7 @@ func TestMacbookDiagnose(t *testing.T) {
},
}
```
in the table-driven testing we gonna define slice of struct that represents test cases, in the example above we have struct that contains callback functions `on: func(*depFields)` and `assert: func(*depFields)` this functions will be called when call test cases and dependencies will be passed that we wanted to `mock` and `assertion calls`

basically in the table-driven testing we will define slice of structs that represents test cases, in the example above we have struct that contains callback functions `on: func(*depFields)` and `assert: func(*testing.T, *depFields)` when we call those methods `type depFields struct{}` will be passed into it in order to `mock` or `assert`
```
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down Expand Up @@ -100,7 +98,7 @@ for _, tt := range tests {
}
```

we iterate all our test cases and run child test functions, on each case we creating dependency of mocks and passing it onto `on` function that prepares us mocks, at the end we also checking test cases `assertion` this helps us to assert number calls that mocked methods are called and etc.
example above we are iterating all test cases and running sub tests, on each case we creating `f := &depFields{}` of mocks and passing it onto `on` function to prepare mocks, at the end of the test we also checking `assertion` of mock calls, this helps us to assert number of calls that mocked methods are called inside the `Diagnose` method.

## Links to read
[Table-Driven tests in Go](https://github.com/golang/go/wiki/TableDrivenTests)
Expand Down
12 changes: 6 additions & 6 deletions computer/macbook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestMacbook(t *testing.T) {
out error

on func(*depFields)
assert func(*depFields)
assert func(*testing.T, *depFields)
}{
{
name: "when CPU usage larger than CPU threshold diagnose return CpuUtilizationError",
Expand All @@ -59,7 +59,7 @@ func TestMacbook(t *testing.T) {
on: func(df *depFields) {
df.cpu.On("Usage").Return(60) // 60% CPU usage
},
assert: func(df *depFields) {
assert: func(t *testing.T, df *depFields) {
df.cpu.AssertNumberOfCalls(t, "Usage", 1)
},
},
Expand All @@ -71,7 +71,7 @@ func TestMacbook(t *testing.T) {
df.cpu.On("Usage").Return(40) // 40% CPU usage less than cpuThreshold
df.gpu.On("Usage").Return(95) // 95% gpu usage larger than gpuThreshold
},
assert: func(df *depFields) {
assert: func(t *testing.T, df *depFields) {
df.cpu.AssertNumberOfCalls(t, "Usage", 1)
df.gpu.AssertNumberOfCalls(t, "Usage", 1)
},
Expand All @@ -86,7 +86,7 @@ func TestMacbook(t *testing.T) {
df.gpu.On("Usage").Return(50) // 50% gpu usage less than gpuThreshold
df.memory.On("FreeMemory").Return(900) // 900 MB free memory left so it is less than 1000 mb threshold
},
assert: func(df *depFields) {
assert: func(t *testing.T, df *depFields) {
df.cpu.AssertNumberOfCalls(t, "Usage", 1)
df.gpu.AssertNumberOfCalls(t, "Usage", 1)
df.memory.AssertNumberOfCalls(t, "FreeMemory", 1)
Expand All @@ -102,7 +102,7 @@ func TestMacbook(t *testing.T) {
df.gpu.On("Usage").Return(50) // 50% gpu usage less than gpuThreshold
df.memory.On("FreeMemory").Return(2000) // 2000 MB free memory left so it is larger than 1000 mb threshold
},
assert: func(df *depFields) {
assert: func(t *testing.T, df *depFields) {
df.cpu.AssertNumberOfCalls(t, "Usage", 1)
df.gpu.AssertNumberOfCalls(t, "Usage", 1)
df.memory.AssertNumberOfCalls(t, "FreeMemory", 1)
Expand Down Expand Up @@ -130,7 +130,7 @@ func TestMacbook(t *testing.T) {
t.Errorf("got %v, want %v", err, tt.out)
}
if tt.assert != nil {
tt.assert(f)
tt.assert(t, f)
}
})
}
Expand Down

0 comments on commit 2238690

Please sign in to comment.