英文:
How to mock DB for unit tests
问题
我有一个类似这样的UserRepo:
type users struct {
*gorm.DB
}
func NewMySqlUsersRepository(db *gorm.DB) repository.IUsers {
return &users{
DB: db,
}
}
对应的方法实现如下:
func (r *users) Save(user *domain.User) (*domain.User, *errors.RestErr) {
err := r.DB.Model(&domain.User{}).Create(&user).Error
if err != nil {
logger.Error("创建用户时发生错误", err)
return nil, errors.NewInternalServerError(errors.ErrSomethingWentWrong)
}
return user, nil
}
对于数据库的模拟,我正在使用sqlmock。但是如何为单元测试模拟这个方法呢?在Gorm中如何为其他数据库查询进行模拟?
英文:
I have UserRepo like this:
type users struct {
*gorm.DB
}
func NewMySqlUsersRepository(db *gorm.DB) repository.IUsers {
return &users{
DB: db,
}
}
Corresponding methods implementation
func (r *users) Save(user *domain.User) (*domain.User, *errors.RestErr) {
err := r.DB.Model(&domain.User{}).Create(&user).Error
if err != nil {
logger.Error("error occurred when create user", err)
return nil, errors.NewInternalServerError(errors.ErrSomethingWentWrong)
}
return user, nil
}
For database mock, I am using sqlmock. But how do I mock this method for unit tests? And in Gorm how to mock for other databases queries?
答案1
得分: 1
在Go语言中进行模拟测试主要是基于Go接口。你需要为存储库创建一个接口,并实现接口的方法。
type IUserRepository interface {
save(user *UserModel) (*userModel, Err)
}
现在,你只需要创建一个模拟结构体和用户结构体,这两个结构体都要实现IUserRepository接口。你可能还想使用流行的模拟/测试框架,比如go-mock或testify来创建模拟对象。
接下来,你需要实现一个工厂方法,根据条件返回相应的模拟结构体。你可以通过上下文、环境变量或其他方式注入条件变量。
func NewMySqlUsersRepositoryFactory(ctx context.Context, env string, db *gorm.DB) repository.IUsers {
if env == "test" {
// 这是一个模拟结构体...
return mock.MockUsers{}
}
// 这是一个实际的结构体...
return &users{
DB: db,
}
}
希望对你有帮助!
英文:
Mocking in Go Is all about Go Interfaces. You will have to create an interface for the repository and implement the Interface methods.
type interface IUserRepository{
save(user *UserModel) (*userModel, Err)
}
Now all you need to do is to create a mock struct along with the user struct. Both of these structs will implement IUserRepository. You might also want to use Popular mocking/testing frameworks like go-mock or testify for creating mocks.
Now, you will have to implement a factory method such that it will return mockStruct depending on the condition. You can inject the condition variable with context, env variable, or any other way.
func NewMySqlUsersRepositoryFactory(ctx context.Context, env string, db *gorm.DB) repository.IUsers {
if env == "test" {
// This is a mocked struct ...
return mock.MockUsers{}
}
// This is a actual struct...
return &users{
DB: db,
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论