你可以通过检查stdout是否有输出来判断是否已经写入。

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

How can I check whether stdout has been written to?

问题

我正在尝试测试一个函数,该函数可以使用"os"包的stdout变量打印到标准输出。我运行了这个函数,并发现它确实打印到了标准输出。现在我正在尝试找出如何使用golang代码证明这个函数是否打印到了标准输出。我是否可以使用"os"包的stdout变量来检查在调用数组中的某个函数后是否已经写入了标准输出?

我尝试通过在os.stdout变量上调用Stat()方法来确定是否已经写入了标准输出,以便可以访问标准输出的大小和最后修改时间,但是大小和最后修改时间并没有反映出函数是否已经写入了标准输出。

英文:

I am trying to test whether a function, which is capable of printing to stdout using the "os" package's stdout variable, actually prints to stdout. I ran this function and I found that it does print to the stdout. Now I am trying to figure out how to prove that this function prints to stdout using golang code. Could I possibly use the "os" package's stdout variable to check whether stdout has been written to after calling one of the functions in the array?

I tried to figure out whether stdout had been written to by calling the Stat() method on the os.stdout variable in order to have access to the size and last modified time of stdout, but the size and last modified time did not reflect the fact that a function had written to the stdout.

答案1

得分: 1

在我看来,处理这个问题的正确方式是以某种方式将io.Writer作为参数传递给你的代码,而不是直接使用stdout。你真的应该避免在没有高级代码重定向的情况下打印到stdout。几乎所有的标准库都采用了这种方法。标准库中很少有默认写入stdout的地方,大多数这样做的地方都有一个更通用的形式,接受一个Writer参数。例如,fmt.Printf只是fmt.Fprintf的一个便利函数。

话虽如此,你可以模拟stdout。如果你的代码将输出推送到stdout,你只需要为stdout创建一个全局变量,然后将输出写入该变量。标准库的测试中就是这样模拟time.Now()的。他们使用一个包全局的now()函数,并根据是否正在运行测试来设置它。

作为最后的手段,假设前面两种方法都不可行,你可以复制当前的os.Stdout,并将其替换为os.Pipe。然后你需要另一个goroutine来监听该管道,并报告返回的内容。

英文:

In my opinion, the correct way to handle this is to make your code take the io.Writer as a parameter in some way instead of using stdout directly. You really should avoid printing to stdout without a way for higher level code to redirect it. Nearly all of the stdlib takes this approach. Very little of the stdlib writes to stdout by default and most of the places that do have a more general form which takes a Writer. For example, fmt.Printf is simply a convenience function for fmt.Fprintf.

That being said, you can mock stdout. If your code is pushing to stdout, all you need to do is make a global variable for stdout and write to there instead. This is done in the stdlib tests to mock time.Now(). Instead of using time.Now, they use a package global now() and set that depending on if a test is being run.

As a last resort, assuming the previous two things are impossible, you can make a copy of the current os.Stdout and replace it with an os.Pipe. Then you need another goroutine to listen on that pipe and report whatever was returned.

huangapple
  • 本文由 发表于 2015年10月18日 02:15:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/33189975.html
匿名

发表评论

匿名网友

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

确定