具有ORM交互的单元测试Go函数

I have written a function:

func AllItems(w http.ResponseWriter, r *http.Request) {
    db, err := gorm.Open("sqlite3", "test.db")
    if err != nil {
        panic("failed to connect database")
    }
    defer db.Close()

    var items [] Item
    db.Find(&items)
    fmt.Println("{}", items)

    json.NewEncoder(w).Encode(items)
}

I want to do unit testing on this. Ideally, unit testing means that each line of the function needs to be tested. I'm not sure how I should test if a database connection is opened and then if it is displaying all the contents of the database. How should I test this code?

This function is the GET endpoint of a simple CRUD application. The code is here.

Refactor your code and break it down into smaller, testable functions which you pass dependencies to. Also create interfaces for the dependencies to make testing easier.

For example:

type myDatabaseInterface interface {
    Find(interface{}) // this signature should match the real db.Find()
}

func AllItems(w http.ResponseWriter, r *http.Request) {
    db, err := gorm.Open("sqlite3", "test.db")
    if err != nil {
        panic("failed to connect database")
    }
    defer db.Close()
    items := findItems(db)
    json.NewEncoder(w).Encode(items)
}

func find(db myDatabaseInterface) ([]Item) {
    var items []Item
    db.Find(&items)
    return items
}

Then you can create mocks for your dependencies and use them in your tests:

type mock struct {}

// mock should implement myDatabaseInterface to be able to pass it to the function
func (m *mock) Find(interface{}) {
    // implement the mock to satisfy your test
}

func Test_find(t *testing.T) {
    m := mock{}
    res := find(m)
    // do testing
}

Instead of calling Open every time you handle a request maybe you should open it outside and have it available to your function. That way the handler becomes so small there's no need to test it really:

func makeAllItemsHandler(db myDatabaseInterface) func(http.ResponseWriter, *http.Request) {
    return func(http.ResponseWriter, *http.Request) {
        items := findItems(db)
        json.NewEncoder(w).Encode(items)
    }
}

Then you can create a db once and for all when you set up your application and pass it to the functions that need it thus removing hard to test code from the functions.