我想在 go 代码中实现 100% 的测试覆盖率。我无法涵盖以下示例 - 任何人都可以帮助我吗?
package example
import (
"io/ioutil"
"log"
)
func checkIfReadable(filename string) (string, error) {
_, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatalf("Cannot read the file... how to add coverage test for this line ?!?")
}
return "", nil
}
func main() {
checkIfReadable("dummy.txt")
}
对此进行一些杜米测试:
package example
import (
"fmt"
"testing"
)
func TestCheckIfReadable(t *testing.T) {
someResult, err := checkIfReadable("dummy.txt")
if len(someResult) > 0 {
fmt.Println("this will not print")
t.Fail()
}
if err != nil {
fmt.Println("this will not print")
t.Fail()
}
}
func TestMain(t *testing.T) {
...
}
问题是log.Fatalf
调用os.Exit
和去引擎死亡。
- 我可以修改代码并用我自己的库替换内置库 - 这使得测试不太可靠。
- 我可以修改代码并创建一个代理、一个包装器和一个....换句话说,将所有调用更改为
log.Fatalf
的非常复杂的机制 - 我可以停止使用内置日志包...什么等于问"GO 内置值多少钱?
- 我可以忍受没有100%的覆盖率
- 我可以用其他东西替换
log.Fataf
- 但是内置log.Fatalf
有什么意义呢? - 我可以尝试破坏系统内存,并根据我的操作系统替换函数的内存地址(...(,所以做一些晦涩难懂和肮脏的事情
- 还有其他想法吗?
使用log.Print
而不是log.Fatal
并返回您在函数checkIfReadable
的签名中声明的错误值。或者不要错误它并将其返回到某个知道如何处理它的地方。
log.Fatal
函数严格用于报告程序的最后一口气。
呼叫log.Fatal
比呼叫 panic 更糟糕(也有log.panic
(,因为它不执行延迟的呼叫。请记住,在 Go 中过度使用panic
被认为是一种糟糕的风格。
获得 100% 测试覆盖率并且同时不失败的一个好方法是使用recover()
来捕捉log.Fatalf()
抛出的恐慌。
以下是用于恢复的文档。我认为它非常适合您的用例。