From 5cb6461252a63b43c690b0f4cf87583c265aee24 Mon Sep 17 00:00:00 2001 From: Lai-YT <381xvmvbib@gmail.com> Date: Sun, 7 Apr 2024 20:54:35 +0800 Subject: [PATCH] Move tests to the `_test` packages Tests are moved to the `_test` package for improved encapsulation. Private functions within the target package are not exposed during testing. Additionally, mock files are suffixed with `_test` to be automatically ignored by coverage tools. The exception to this rule is tests related to the database. These tests remain in the same package as the database functions to allow access to the internal database handle for checking the state of the database. --- Makefile | 2 +- core/core_test.go | 32 ++++++++++--------- .../{mock_storage.go => mock_storage_test.go} | 18 ++++++----- endpoint/endpoint_test.go | 23 ++++++------- endpoint/{mock_core.go => mock_core_test.go} | 6 ++-- 5 files changed, 43 insertions(+), 38 deletions(-) rename core/{mock_storage.go => mock_storage_test.go} (84%) rename endpoint/{mock_core.go => mock_core_test.go} (94%) diff --git a/Makefile b/Makefile index 289911b..2d6f4c0 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ PACKAGES ?= $(shell $(GO) list ./...) GOFILES := $(shell find . -name "*.go") TESTTAGS ?= "-test.shuffle=on" COVERPROFILE ?= coverage.out -COVEREXCLUDE ?= "mock" +COVEREXCLUDE ?= "$$^" .PHONY: test test: diff --git a/core/core_test.go b/core/core_test.go index eaf8ff7..395d25f 100644 --- a/core/core_test.go +++ b/core/core_test.go @@ -1,4 +1,4 @@ -package core +package core_test import ( "errors" @@ -6,6 +6,8 @@ import ( "os" "testing" + core "todolist/core" + log "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" @@ -23,13 +25,13 @@ type testEnv struct { t *testing.T ctrl *gomock.Controller mockAccessor *MockStorageAccessor - core *TheCore + core *core.TheCore } func newTestEnv(t *testing.T) *testEnv { ctrl := gomock.NewController(t) mockAccessor := NewMockStorageAccessor(ctrl) - theCore := NewCore(mockAccessor) + theCore := core.NewCore(mockAccessor) return &testEnv{t, ctrl, mockAccessor, theCore} } @@ -39,14 +41,14 @@ func TestCreateItem(t *testing.T) { e := newTestEnv(t) e.mockAccessor.EXPECT(). Create(gomock.Any()). - DoAndReturn(func(item *TodoItem) (int, error) { + DoAndReturn(func(item *core.TodoItem) (int, error) { id := 1 item.ID = id return id, nil }) // act - want := TodoItem{ID: 1, Description: "some description", Completed: false} + want := core.TodoItem{ID: 1, Description: "some description", Completed: false} got := e.core.CreateItem(want.Description) // assert @@ -59,8 +61,8 @@ func TestUpdateItem(t *testing.T) { e := newTestEnv(t) e.mockAccessor.EXPECT(). Read(gomock.Any()). - DoAndReturn(func(func(TodoItem) bool) []TodoItem { - return []TodoItem{ + DoAndReturn(func(func(core.TodoItem) bool) []core.TodoItem { + return []core.TodoItem{ {ID: 1, Description: "some description", Completed: false}, } }) @@ -69,7 +71,7 @@ func TestUpdateItem(t *testing.T) { Return(nil) // act - want := TodoItem{ID: 1, Description: "some description", Completed: true} + want := core.TodoItem{ID: 1, Description: "some description", Completed: true} got, err := e.core.UpdateItem(want.ID, want.Completed) // assert: the item should be updated and returned without error @@ -84,8 +86,8 @@ func TestUpdateItemNotFound(t *testing.T) { e := newTestEnv(t) e.mockAccessor.EXPECT(). Read(gomock.Any()). - DoAndReturn(func(func(TodoItem) bool) []TodoItem { - return []TodoItem{} + DoAndReturn(func(func(core.TodoItem) bool) []core.TodoItem { + return []core.TodoItem{} }) // act @@ -94,7 +96,7 @@ func TestUpdateItemNotFound(t *testing.T) { _, err := e.core.UpdateItem(id, completed) // assert: an error should be returned - assert.IsType(t, TodoItemNotFoundError{}, err) + assert.IsType(t, core.TodoItemNotFoundError{}, err) } // TestDeleteItem Given an id and the storage accessor returns no error, when DeleteItem is called, then no error is returned. @@ -134,20 +136,20 @@ func TestDeleteItemError(t *testing.T) { func TestGetItems(t *testing.T) { // arrange e := newTestEnv(t) - mockItems := [2]TodoItem{ + mockItems := [2]core.TodoItem{ {ID: 1, Description: "some description", Completed: false}, {ID: 2, Description: "another description", Completed: true}, } e.mockAccessor.EXPECT(). Read(gomock.Any()). - DoAndReturn(func(func(TodoItem) bool) []TodoItem { + DoAndReturn(func(func(core.TodoItem) bool) []core.TodoItem { // With completed = false. - return []TodoItem{mockItems[0]} + return []core.TodoItem{mockItems[0]} }) // act completed := false - want := []TodoItem{mockItems[0]} + want := []core.TodoItem{mockItems[0]} got := e.core.GetItems(completed) // assert diff --git a/core/mock_storage.go b/core/mock_storage_test.go similarity index 84% rename from core/mock_storage.go rename to core/mock_storage_test.go index e5c9e43..12a7f5b 100644 --- a/core/mock_storage.go +++ b/core/mock_storage_test.go @@ -1,17 +1,19 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: storage.go +// Source: core/storage.go // // Generated by this command: // -// mockgen -source=storage.go -destination=mock_storage.go -package=core +// mockgen -source=core/storage.go -destination=core/mock_storage_test.go -package=core_test // -// Package core is a generated GoMock package. -package core +// Package core_test is a generated GoMock package. +package core_test import ( reflect "reflect" + core "todolist/core" + gomock "go.uber.org/mock/gomock" ) @@ -39,7 +41,7 @@ func (m *MockStorageAccessor) EXPECT() *MockStorageAccessorMockRecorder { } // Create mocks base method. -func (m *MockStorageAccessor) Create(arg0 *TodoItem) (int, error) { +func (m *MockStorageAccessor) Create(arg0 *core.TodoItem) (int, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Create", arg0) ret0, _ := ret[0].(int) @@ -68,10 +70,10 @@ func (mr *MockStorageAccessorMockRecorder) Delete(id any) *gomock.Call { } // Read mocks base method. -func (m *MockStorageAccessor) Read(where func(TodoItem) bool) []TodoItem { +func (m *MockStorageAccessor) Read(where func(core.TodoItem) bool) []core.TodoItem { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Read", where) - ret0, _ := ret[0].([]TodoItem) + ret0, _ := ret[0].([]core.TodoItem) return ret0 } @@ -82,7 +84,7 @@ func (mr *MockStorageAccessorMockRecorder) Read(where any) *gomock.Call { } // Update mocks base method. -func (m *MockStorageAccessor) Update(todo TodoItem) error { +func (m *MockStorageAccessor) Update(todo core.TodoItem) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Update", todo) ret0, _ := ret[0].(error) diff --git a/endpoint/endpoint_test.go b/endpoint/endpoint_test.go index d05578e..04dbec9 100644 --- a/endpoint/endpoint_test.go +++ b/endpoint/endpoint_test.go @@ -1,4 +1,4 @@ -package endpoint +package endpoint_test import ( "encoding/json" @@ -15,6 +15,7 @@ import ( "testing" "todolist/core" + "todolist/endpoint" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" @@ -40,7 +41,7 @@ type testEnv struct { func newTestEnv(t *testing.T) *testEnv { ctrl := gomock.NewController(t) mockCore := NewMockCore(ctrl) - SetCore(mockCore) + endpoint.SetCore(mockCore) return &testEnv{ t: t, router: mux.NewRouter(), @@ -76,7 +77,7 @@ func TestHealthz(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/healthz" - e.router.HandleFunc(pattern, Healthz) + e.router.HandleFunc(pattern, endpoint.Healthz) // act: make a request to the /healthz endpoint request, _ := http.NewRequest(http.MethodGet, pattern, nil) @@ -98,7 +99,7 @@ func TestCreateItem(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo" - e.router.HandleFunc(pattern, CreateItem) + e.router.HandleFunc(pattern, endpoint.CreateItem) testDescription := "test" e.mockCore.EXPECT(). CreateItem(testDescription). @@ -125,7 +126,7 @@ func TestUpdateItem(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo/{id}" - e.router.HandleFunc(pattern, UpdateItem) + e.router.HandleFunc(pattern, endpoint.UpdateItem) testID := 1 testCompleted := true e.mockCore.EXPECT(). @@ -153,7 +154,7 @@ func TestUpdateItemError(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo/{id}" - e.router.HandleFunc(pattern, UpdateItem) + e.router.HandleFunc(pattern, endpoint.UpdateItem) e.mockCore.EXPECT(). UpdateItem(gomock.Any(), gomock.Any()). Return(core.TodoItem{} /* dummy */, errors.New("test error")) @@ -183,7 +184,7 @@ func TestDeleteItem(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo/{id}" - e.router.HandleFunc(pattern, DeleteItem) + e.router.HandleFunc(pattern, endpoint.DeleteItem) testID := 1 e.mockCore.EXPECT(). DeleteItem(testID). @@ -206,7 +207,7 @@ func TestDeleteItemError(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo/{id}" - e.router.HandleFunc(pattern, DeleteItem) + e.router.HandleFunc(pattern, endpoint.DeleteItem) e.mockCore.EXPECT(). DeleteItem(gomock.Any()). Return(errors.New("test error")) @@ -231,7 +232,7 @@ func TestGetItemsCompleted(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo" - e.router.HandleFunc(pattern, GetItems) + e.router.HandleFunc(pattern, endpoint.GetItems) todoItems := []core.TodoItem{ {ID: 1, Description: "test1", Completed: true}, {ID: 3, Description: "test3", Completed: true}, @@ -257,7 +258,7 @@ func TestGetItemIncomplete(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo" - e.router.HandleFunc(pattern, GetItems) + e.router.HandleFunc(pattern, endpoint.GetItems) todoItems := []core.TodoItem{ {ID: 2, Description: "test2", Completed: false}, {ID: 4, Description: "test4", Completed: false}, @@ -283,7 +284,7 @@ func TestGetItemsAll(t *testing.T) { // arrange e := newTestEnv(t) pattern := "/todo" - e.router.HandleFunc(pattern, GetItems) + e.router.HandleFunc(pattern, endpoint.GetItems) todoItems := []core.TodoItem{ {ID: 1, Description: "test1", Completed: true}, {ID: 2, Description: "test2", Completed: false}, diff --git a/endpoint/mock_core.go b/endpoint/mock_core_test.go similarity index 94% rename from endpoint/mock_core.go rename to endpoint/mock_core_test.go index f2e8a71..fd96697 100644 --- a/endpoint/mock_core.go +++ b/endpoint/mock_core_test.go @@ -3,11 +3,11 @@ // // Generated by this command: // -// mockgen -source=core/core.go -destination=endpoint/mock_core.go -package=endpoint +// mockgen -source=core/core.go -destination=endpoint/mock_core_test.go -package=endpoint_test // -// Package endpoint is a generated GoMock package. -package endpoint +// Package endpoint_test is a generated GoMock package. +package endpoint_test import ( reflect "reflect"