如何模拟 DB 进行单元测试

时间:2021-07-19 11:47:47

标签: mysql unit-testing go mocking go-gorm

我有这样的 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("error occurred when create user", err)
    return nil, errors.NewInternalServerError(errors.ErrSomethingWentWrong)
  }

  return user, nil
}

对于数据库模拟,我使用的是 sqlmock。但是我如何为单元测试模拟这个方法?在 Gorm 中如何模拟其他数据库查询?

1 个答案:

答案 0 :(得分:1)

Go 中的 Mock 是关于 Go 接口的。您必须为存储库创建一个接口并实现接口方法。

type interface IUserRepository{
     save(user *UserModel) (*userModel, Err)
}

现在您需要做的就是创建一个模拟结构以及用户结构。这两个结构都将实现 IUserRepository。您可能还想使用流行的模拟/测试框架(如 go-mocktestify)来创建模拟。

现在,您必须实现一个工厂方法,以便它根据条件返回 mockStruct。您可以使用上下文、环境变量或任何其他方式注入条件变量。

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,
    }
}