Go测试覆盖率 – Go工具无法识别err != nil的返回值

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

Go Test Coverage - Go Tool Not Recognize err != nil returns

问题

我正在学习关于在Golang中进行测试覆盖率的一些内容,并遇到了一些有趣的问题。

我有一个相当基本的代码来调用一个API并执行http.Client.Do(request)。执行后,我检查错误并返回它(如果找到错误)。

resp, err := Client.Do(request)

if err != nil {
	return response, err
}

此外,我还为此添加了测试。在测试中,我模拟了Do函数并返回一个错误。

mocks.DoFunc = func(*http.Request) (*http.Response, error) {
	return nil, errors.New("hello world")
}

当我记录if err != nil条件时,我可以看到我的代码正在运行,并被这个简单的评估所捕获。

我的问题是,在执行go tool cover -html=coverage.out时,输出表明这个条件没有被覆盖。

所以,为什么我在记录时可以检查它,但是go tool却没有检测到它,我漏掉了什么?

英文:

I am learning a bit about test coverage in Golang and having some interesting issues.

I have a fair basic code for calling an API and executing the http.Client.Do(request). After the execution I check for error and return it if its found.

resp, err := Client.Do(request)

if err != nil {
	return response, err
}

Also, I have added tests for it. Where I am mocking the Do function and returning an error.

mocks.DoFunc = func(*http.Request) (*http.Response, error) {
	return nil, errors.New("hello world")
}

When I log the if err != nil condition, I can see that my code is running and being catch by this simple evaluation.

My problem starts when executing go tool cover -html=coverage.out. The output indicates that this condition is not covered.

SO, why I can check for it when logging and go tool is not detecting it, what am I missing?

答案1

得分: 2

好的,以下是翻译好的内容:

好的。不确定,但是有效。

似乎测试顺序对于测试覆盖率非常重要,创建从最少到最先评估if err != nil的测试可以解决问题。

我的代码执行了一个简单的API请求:

  1. 创建一个响应对象
  2. 格式化URL + ID
  3. 创建一个Http.NewRequest
  4. 评估NewRequest的错误
  5. 执行http.Client.Do(request)
  6. 评估Do的错误
  7. 以此类推...

...

response := &Response{}

url := fmt.Sprintf(pokeapiURLById, pokeId)

request, err := http.NewRequest(http.MethodGet, url, nil)

if err != nil {
	return nil, err
}

resp, err := Client.Do(request)

if err != nil {
	return nil, err
}

...

测试按照以下顺序创建:

func TestFetchById_WhenHttpNewRequestFails(t *testing.T) {...}

func TestFetchById_WhenClientDoFails(t *testing.T) {...}

首先,我测试了NewRequest的错误,然后是Client.Do(req)的错误。通过这种方式,我得到了80%的测试覆盖率...

当我改变了测试方法的顺序:

func TestFetchById_WhenClientDoFails(t *testing.T) {...}

func TestFetchById_WhenHttpNewRequestFails(t *testing.T) {...}

我获得了100%的测试覆盖率。
我不知道这是否是一个问题,或者它应该是这样的...但是,现在它运行得很好。

英文:

Ok. Not sure, but worked.

It seems that the Test Order is really important on TestCoverage, creating tests that evaluate from the least to first if err != nil did the trick.

My code do a simple fetch an API:

  1. Create a Response object
  2. Format the URL + ID
  3. Creates a Http.NewREquest
  4. Evaluates NewRequest err
  5. Executes http.Client.Do(request)
  6. Evaluates Do err
  7. And So on and on...

...

response := &Response{}

url := fmt.Sprintf(pokeapiURLById, pokeId)

request, err := http.NewRequest(http.MethodGet, url, nil)

if err != nil {
	return nil, err
}

resp, err := Client.Do(request)

if err != nil {
	return nil, err
}

...

Tests where created in the following order.

func TestFetchById_WhenHttpNewRequestFails(t *testing.T) {...

func TestFetchById_WhenClientDoFails(t *testing.T) {...

First, I test the NewRequest err and then Client.Do(req) err. And this way I got 80% of test coverage....

When I changed the order of my test methods:

func TestFetchById_WhenClientDoFails(t *testing.T) {...

func TestFetchById_WhenHttpNewRequestFails(t *testing.T) {...

I Have 100% of test coverage.
I do not know if its an issue or it supposed to be like that... But, now, it's working good.

huangapple
  • 本文由 发表于 2022年1月7日 21:12:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/70621781.html
匿名

发表评论

匿名网友

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

确定