Golang gorm模拟测试

huangapple go评论92阅读模式
英文:

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>



huangapple
  • 本文由 发表于 2017年1月7日 00:31:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/41510003.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定