你如何在你的 Golang 代码中测试 filepath.Abs 失败的情况?

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

How do you test filepath.Abs failure in your Golang code?

问题

在我的Go代码中,我不得不多次使用filepath.Abs(),这可能会导致我的方法返回不同的错误。

func (s *service) myFunc(path string) error {
	dir := s.Component().Dir()
	absDir, err := filepath.Abs(dir)

	if err != nil {
		return my_errors.NewFailedToGetAbsoluteComponentDir()
	}

	absPath, err := filepath.Abs(path)
	if absPath != nil {
		return my_errors.NewFailedToGetAbsPath()
	}

	// 更多代码...
	return nil
}

在我的单元测试中,我想要测试它,但我唯一能想到的方法是将filepath.Abs作为一个依赖注入到我的结构体中。

还有其他我没有考虑到的方法吗?
或者你认为这种测试是不必要的吗?

英文:

In my Go code, I have to use filepath.Abs() several times, which may lead to different errors that my method returns.

func (s *service) myFunc(path string) error {
	dir := s.Component().Dir()
	absDir, err := filepath.Abs(dir)

	if err != nil {
		return my_errors.NewFailedToGetAbsoluteComponentDir()
	}

	absPath, err := filepath.Abs(path)
	if absPath != nil {
		return my_errors.NewFailedToGetAbsPath()
	}

	// more code...
	return nil
}

In my unit test, I want to test it, but the only way I can think of is to inject filepath.Abs as a dependency into my struct.

Is there any other way I did not think of?
Or do you think that this kind of test is unnecessary?

答案1

得分: 4

如果我们查看标准库中filepath.Abs函数的源代码,我们可以看到它在返回错误时的情况,然后尝试在我们的测试中触发该条件。filepath.Abs根据编译的目标操作系统的不同有不同的实现,但是例如Unix实现看起来像这样:

func unixAbs(path string) (string, error) {
	if IsAbs(path) {
		return Clean(path), nil
	}
	wd, err := os.Getwd()
	if err != nil {
		return "", err
	}
	return Join(wd, path), nil
}

因此,它只会在os.Getwd()返回错误时才返回错误。让os.Getwd()返回错误的一种简单方法是确保当前工作目录不存在。可以在测试中这样做:

	dir, _ := os.MkdirTemp("", "") // 创建一个临时目录
	os.Chdir(dir)                  // 切换到该目录
	os.RemoveAll(dir)              // 删除该目录
	fmt.Println(os.Getwd())        // 现在将返回一个错误

现在这个方法的问题是它会改变整个进程的工作目录,这可能会干扰其他测试。因此,重要的是在此测试运行后重置工作目录,并确保不同时运行依赖于工作目录的其他测试。

要重置工作目录,在测试开始时添加以下代码:

	origWd, _ := os.Getwd()
	t.Cleanup(func() {
		os.Chdir(origWd)
	})

并且为了确保没有其他冲突的测试同时运行,在测试中不要调用t.Parallel()

这是否值得测试呢?通常不值得。你的工作目录有多少可能是无效的?在大多数情况下,几乎不可能。如果是这种情况,我建议不要测试代码的这部分。

然而,如果你正在构建一个命令行工具,工作目录经常变化或者常常是未知的,那么这样的测试可能确实是值得的。

在你付出这么多努力之前,请确保你的测试提供了一些实际价值 你如何在你的 Golang 代码中测试 filepath.Abs 失败的情况?

我制作了一个视频讨论这个问题,以及对该主题感兴趣的任何人的一般问题:回答StackOverflow:如何测试Go中的filepath.Abs?

英文:

If we look at the source code for the filepath.Abs function in the standard library, we can see when it returns an error, and then try to trigger that condition in our tests. filepath.Abs has different implementations depending on which target OS it's compiled for, but the Unix implementation, for example, looks like this:

func unixAbs(path string) (string, error) {
	if IsAbs(path) {
		return Clean(path), nil
	}
	wd, err := os.Getwd()
	if err != nil {
		return "", err
	}
	return Join(wd, path), nil
}

So the only time it will ever return an error is when os.Getwd() returns an error. An easy way to make os.Getwd() return an error is to ensure that your current working directory doesn't exist. This can be done in a test as so:

	dir, _ := os.MkdirTemp("", "") // Create a temporary directory
	os.Chdir(dir)                  // Change to that directory
	os.RemoveAll(dir)              // Delete that directory
	fmt.Println(os.Getwd())        // This will now return an error

Now this has the problem that it changes the working directory for the entire process, which could interfere with other tests. So it's important to both reset the working directory after this test runs, and also to make sure that no other tests that depend on the working directory run at the same time.

To reset it, put this at the beginning of your test:

	origWd, _ := os.Getwd()
	t.Cleanup(func() {
		os.Chdir(origWd)
	})

And to make sure no other conflicting tests run at the same time, don't call t.Parallel() in your test.

<hr>

Is it worth it to test this? Usually not. How often is your working directory likely to be invalid? Under most circumstances, never. If that describes you, I simply wouldn't test this part of your code.

However, if you're building a CLI tool, for example, where the working directory is in constant flux or often unknown, then such a test may indeed be worth it.

Just make sure your test provides some actual value, before you go to this much effort 你如何在你的 Golang 代码中测试 filepath.Abs 失败的情况?

<hr>

I've made a video discussing this question, and the general question for anyone interested in a longer discussion of the topic: Answering StackOverflow: How do you test filepath.Abs in Go?

huangapple
  • 本文由 发表于 2023年3月16日 15:26:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/75753182.html
匿名

发表评论

匿名网友

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

确定