Golang测试覆盖率问题如何解决

Golang测试覆盖率问题如何解决

func (ts *service) SaveAppealAndReInspection(t *model.Profile) error {
	t.ID = bson.NewObjectId()
	t.AppealID = ts.Shared.NextCount("AppealAndReinspection")
	return ts.AppealDal.Insert(t)
}

//这是我的测试用例

func TestDBErrorWhileInserting(t *testing.T) {
	InsertFlag = "mongoerror"
	tempProfile := new(model.Profile)
	err := service.SaveTCAppealAndReInspection(tempProfile )
	if err == nil {
		t.Errorf("预期会出现数据库错误但得到的是nil")
	}
	InsertFlag = ""
	err = service.SaveTCAppealAndReInspection(tempProfile )
	if err != nil {
		t.Errorf("预期为nil但得到 " + err.Error())
	}
}

我的代码覆盖率只有0.7% 我哪里遗漏了 func (ts *service) SaveAppealAndReInspection(t *model.Profile) error - 返回错误,所以我测试了它是否返回错误。 或者告诉我我是否写错了。


更多关于Golang测试覆盖率问题如何解决的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang测试覆盖率问题如何解决的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你的测试用例只覆盖了函数的部分路径,导致覆盖率较低。主要问题在于:

  1. 未测试正常插入路径:你的测试只验证了数据库错误的情况,但没有测试正常插入成功的场景
  2. 依赖全局变量:使用 InsertFlag 这种全局变量来控制行为不是最佳实践
  3. 未模拟依赖:没有对 ts.AppealDal.Insert(t) 进行模拟

以下是改进后的测试代码示例:

// 使用接口来模拟依赖
type AppealDal interface {
    Insert(t *model.Profile) error
}

type service struct {
    AppealDal AppealDal
    Shared    *sharedService
}

// 测试用例
func TestSaveAppealAndReInspection_Success(t *testing.T) {
    mockDal := &MockAppealDal{
        InsertFunc: func(t *model.Profile) error {
            return nil
        },
    }
    
    svc := &service{
        AppealDal: mockDal,
        Shared:    &sharedService{},
    }
    
    profile := &model.Profile{}
    err := svc.SaveAppealAndReInspection(profile)
    
    if err != nil {
        t.Errorf("预期无错误,但得到: %v", err)
    }
    
    if profile.ID == "" {
        t.Error("预期Profile ID被设置")
    }
    
    if profile.AppealID == 0 {
        t.Error("预期AppealID被设置")
    }
}

func TestSaveAppealAndReInspection_InsertError(t *testing.T) {
    expectedErr := errors.New("数据库插入错误")
    
    mockDal := &MockAppealDal{
        InsertFunc: func(t *model.Profile) error {
            return expectedErr
        },
    }
    
    svc := &service{
        AppealDal: mockDal,
        Shared:    &sharedService{},
    }
    
    profile := &model.Profile{}
    err := svc.SaveAppealAndReInspection(profile)
    
    if err != expectedErr {
        t.Errorf("预期错误 %v,但得到 %v", expectedErr, err)
    }
}

// Mock实现
type MockAppealDal struct {
    InsertFunc func(t *model.Profile) error
}

func (m *MockAppealDal) Insert(t *model.Profile) error {
    if m.InsertFunc != nil {
        return m.InsertFunc(t)
    }
    return nil
}

type MockSharedService struct {
    NextCountFunc func(key string) int
}

func (m *MockSharedService) NextCount(key string) int {
    if m.NextCountFunc != nil {
        return m.NextCountFunc(key)
    }
    return 1
}

这个改进版本:

  • 测试了正常插入成功的路径
  • 测试了插入失败的路径
  • 使用接口和mock来隔离依赖
  • 验证了函数对输入参数的修改(ID和AppealID的设置)

通过这种方式,你可以获得接近100%的测试覆盖率,因为覆盖了函数的所有执行路径。

回到顶部