package main
import (
"errors"
"fmt"
"testing"
"time"
)
func Add(a, b int) int {
return a + b
}
func Divide(a, b float64) (float64, error) {
if b == 0 {
return 0, errors.New("division by zero")
}
return a / b, nil
}
type Calculator struct {
operations int
}
func (c *Calculator) Add(a, b int) int {
c.operations++
return a + b
}
func (c *Calculator) GetOperations() int {
return c.operations
}
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Add(2, 3) = %d; want 5", result)
}
}
func TestDivide(t *testing.T) {
tests := []struct {
name string
a, b float64
expected float64
wantErr bool
}{
{"valid division", 10, 2, 5, false},
{"division by zero", 10, 0, 0, true},
{"decimal result", 7, 2, 3.5, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := Divide(tt.a, tt.b)
if (err != nil) != tt.wantErr {
t.Errorf("Divide() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !tt.wantErr && result != tt.expected {
t.Errorf("Divide() = %v, want %v", result, tt.expected)
}
})
}
}
func TestCalculator(t *testing.T) {
calc := &Calculator{}
result := calc.Add(5, 3)
if result != 8 {
t.Errorf("Add(5, 3) = %d; want 8", result)
}
if calc.GetOperations() != 1 {
t.Errorf("Operations = %d; want 1", calc.GetOperations())
}
}
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(i, i+1)
}
}
func BenchmarkCalculator(b *testing.B) {
calc := &Calculator{}
b.ResetTimer()
for i := 0; i < b.N; i++ {
calc.Add(i, i+1)
}
}
func ExampleAdd() {
fmt.Println(Add(2, 3))
}
func FuzzAdd(f *testing.F) {
f.Add(1, 2)
f.Add(0, 0)
f.Add(-5, 10)
f.Fuzz(func(t *testing.T, a, b int) {
result := Add(a, b)
expected := a + b
if result != expected {
t.Errorf("Add(%d, %d) = %d; want %d", a, b, result, expected)
}
})
}
type MockDatabase struct {
data map[string]string
}
func NewMockDatabase() *MockDatabase {
return &MockDatabase{
data: make(map[string]string),
}
}
func (m *MockDatabase) Get(key string) (string, bool) {
val, ok := m.data[key]
return val, ok
}
func (m *MockDatabase) Set(key, value string) {
m.data[key] = value
}
type Service struct {
db Database
}
type Database interface {
Get(string) (string, bool)
Set(string, string)
}
func NewService(db Database) *Service {
return &Service{db: db}
}
func (s *Service) GetUser(id string) (string, bool) {
return s.db.Get("user:" + id)
}
func TestServiceWithMock(t *testing.T) {
mock := NewMockDatabase()
mock.Set("user:1", "Alice")
service := NewService(mock)
user, ok := service.GetUser("1")
if !ok {
t.Error("Expected user to exist")
}
if user != "Alice" {
t.Errorf("Expected Alice, got %s", user)
}
}
func TestWithTimeout(t *testing.T) {
done := make(chan bool)
go func() {
time.Sleep(100 * time.Millisecond)
done <- true
}()
select {
case <-done:
case <-time.After(1 * time.Second):
t.Error("Test timed out")
}
}
func TestParallel(t *testing.T) {
tests := []struct {
name string
a, b int
want int
}{
{"small", 1, 2, 3},
{"medium", 10, 20, 30},
{"large", 100, 200, 300},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
if got := Add(tt.a, tt.b); got != tt.want {
t.Errorf("Add() = %v, want %v", got, tt.want)
}
})
}
}
func TestCleanup(t *testing.T) {
resource := "opened"
t.Cleanup(func() {
resource = "closed"
t.Log("Resource cleaned up")
})
t.Logf("Resource is %s", resource)
}
func TestSkip(t *testing.T) {
if testing.Short() {
t.Skip("Skipping in short mode")
}
t.Log("This test only runs when -short is not set")
}
func main() {
fmt.Println("Run tests with: go test -v")
}