testing_mock_test.go 1.62 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
// Copyright 2020 The Swarm Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package jsonhttptest_test

import (
	"errors"
	"fmt"
	"testing"
)

// assert is a test helper that validates a functionality of another helper
// function by mocking Errorf, Fatal and Helper methods on testing.TB.
func assert(t *testing.T, wantError, wantFatal string, f func(m *mock)) {
	t.Helper()

	defer func() {
		if v := recover(); v != nil {
			if err, ok := v.(error); ok && errors.Is(err, errFailed) {
				return // execution of the goroutine is stopped by a mock Fatal function
			}
			t.Fatalf("panic: %v", v)
		}
	}()

	m := &mock{
		wantError: wantError,
		wantFatal: wantFatal,
	}

	f(m)

	if !m.isHelper { // Request function is tested and it must be always a helper
		t.Error("not a helper function")
	}

	if m.gotError != m.wantError {
		t.Errorf("got error %q, want %q", m.gotError, m.wantError)
	}

	if m.gotFatal != m.wantFatal {
		t.Errorf("got error %v, want %v", m.gotFatal, m.wantFatal)
	}
}

// mock provides the same interface as testing.TB with overridden Errorf, Fatal
// and Heleper methods.
type mock struct {
	testing.TB
	isHelper  bool
	gotError  string
	wantError string
	gotFatal  string
	wantFatal string
}

func (m *mock) Helper() {
	m.isHelper = true
}

func (m *mock) Errorf(format string, args ...interface{}) {
	m.gotError = fmt.Sprintf(format, args...)
}

func (m *mock) Fatal(args ...interface{}) {
	m.gotFatal = fmt.Sprint(args...)
	panic(errFailed) // terminate the goroutine to detect it in the assert function
}

var errFailed = errors.New("failed")