英文:
Golang gorm mocking
问题
我在我的项目中使用gorm。我能否在没有数据库连接的情况下对这个数据库 orm 进行测试模拟?我们在 CI 工具中遇到了问题,因为我没有数据库或者数据库中没有足够的数据进行测试。另一种方式是,我不想为每次测试都设置一个数据库,因为在这些情况下,CI 工具每次都会创建一个容器来运行测试。
对于测试与数据库相关的方法,最好的方式是什么?我在我的解决方案中使用了依赖注入,所以很容易用模拟数据库替换真实数据库。但是 gorm 有很多与 orm 相关的函数。
以下是一个示例处理程序:
func tokenIntrospectionHandler(db *gorm.DB) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
token := req.FormValue("token")
var resp Response
json.NewEncoder(w).Encode(resp)
})
}
英文:
I am using gorm in my projects. Can I mock this database orm for testing without database connection? The problem we have CI tools where I don't have database or database with enough data for testing. The other way, I don't want to setup a database for every time I'm testing, because in these cases the CI tool create every time a container just for run the tests.
Whet is the best way for testing database related methods? I am using dependency injection in my solutions so it is easy to replace the database with a mocked database. But the gorm have many orm related function.
This is a handler for example:
func tokenIntrospectionHandler(db *gorm.DB) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
defer req.Body.Close()
token := req.FormValue("token")
var resp Response
json.NewEncoder(w).Encode(resp)
})
}
答案1
得分: 4
对于单元测试,这个库看起来很适合模拟 gorm.DB
:https://github.com/DATA-DOG/go-sqlmock
以下是他们网站上的一个示例。你只需要创建一个模拟对象,然后创建一个数据库对象,设置方法调用的期望,运行你的测试代码,最后检查期望是否满足。
// 一个成功的测试用例
func TestShouldUpdateStats(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("在打开存根数据库连接时不应该出现错误:%s", err)
}
defer db.Close()
mock.ExpectBegin()
mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()
// 现在我们执行我们的方法
if err = recordStats(db, 2, 3); err != nil {
t.Errorf("在更新统计数据时不应该出现错误:%s", err)
}
// 确保所有的期望都被满足
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("存在未满足的期望:%s", err)
}
}
英文:
for unit tests, this looks pretty good to mock gorm.DB
: https://github.com/DATA-DOG/go-sqlmock
Here's an example from their site. You just creates the mock, then the DB, sets the expectations for the method calls, then run your code under testing and finally check if the expectations are met.
// a successful case
func TestShouldUpdateStats(t *testing.T) {
db, mock, err := sqlmock.New()
if err != nil {
t.Fatalf("an error '%s' was not expected when opening a stub database connection", err)
}
defer db.Close()
mock.ExpectBegin()
mock.ExpectExec("UPDATE products").WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectExec("INSERT INTO product_viewers").WithArgs(2, 3).WillReturnResult(sqlmock.NewResult(1, 1))
mock.ExpectCommit()
// now we execute our method
if err = recordStats(db, 2, 3); err != nil {
t.Errorf("error was not expected while updating stats: %s", err)
}
// we make sure that all expectations were met
if err := mock.ExpectationsWereMet(); err != nil {
t.Errorf("there were unfulfilled expectations: %s", err)
}
}
</details>
# 答案2
**得分**: -1
如果你正在使用干净架构,只需模拟你的存储库,这样会更好。
<details>
<summary>英文:</summary>
if you are using clean architecture just mock your repository its a lot better
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论