From 2238690d334f3235b5da87ce61c669fed2520ebd Mon Sep 17 00:00:00 2001 From: jurabek Date: Sat, 13 Mar 2021 13:25:40 +0100 Subject: [PATCH] sub test passed into assertion --- README.md | 10 ++++------ computer/macbook_test.go | 12 ++++++------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 377e010..e8f4273 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 ``` @@ -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) { @@ -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) diff --git a/computer/macbook_test.go b/computer/macbook_test.go index 72923ae..3eca924 100644 --- a/computer/macbook_test.go +++ b/computer/macbook_test.go @@ -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", @@ -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) }, }, @@ -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) }, @@ -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) @@ -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) @@ -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) } }) }