英文:
how to test the result in goroutine without wait in test
问题
当我在使用golang时,有时候需要在goroutine中测试结果,我之前使用time.Sleep来测试,我想知道是否有更好的方法来进行测试。
假设我有如下的示例代码:
func Hello() {
go func() {
// 做一些事情,并将结果存储在数据库中
}()
// 做一些其他事情
}
当我测试这个函数时,我想要同时测试goroutine中的结果,我目前是这样做的:
func TestHello(t *testing.T) {
Hello()
time.Sleep(time.Second) // 等待一段时间,以便goroutine完成
// 测试goroutine的结果
}
是否有更好的方法来进行这个测试?
基本上,在实际逻辑中,我不关心goroutine中的结果,我不需要等待它完成。但是在测试中,我想要在它完成后进行检查。
英文:
When I do ut of golang, I sometimes need to test the result in goroutine, I was using time.Sleep to test, I am wondering is there any better way to test.
let's say I have an example code like this
func Hello() {
go func() {
// do something and store the result for example in db
}()
// do something
}
Then when I test the func, I want to test both result in goroutine,
I am doing this:
func TestHello(t *testing.T) {
Hello()
time.Sleep(time.Second) // sleep for a while so that goroutine can finish
// test the result of goroutine
}
is there any better way to test this?
Basically, in real logic, I don't care the result in goroutine, I don't need to wait for it finished. but in test, I want to check after it finished.
答案1
得分: 7
大多数关于“如何测试X?”的问题往往归结为X太大。
在你的情况下,最简单的解决方案是在测试中不使用goroutines。将每个函数单独进行测试。将你的代码更改为:
func Hello() {
go updateDatabase()
doSomething()
}
func updateDatabase() {
// 做一些事情并将结果存储在数据库中
}
func doSomething() {
// 做一些事情
}
然后为updateDatabase
和doSomething
编写单独的测试。
英文:
Most questions of "How do I test X?" tend to boil down to X being too big.
In your case, the simplest solution is not to use goroutines in tests. Test each function in isolation. Change your code to:
func Hello() {
go updateDatabase()
doSomething()
}
func updateDatabase() {
// do something and store the result for example in db
}
func doSomething() {
// do something
}
Then write separate tests for updateDatabase
and doSomething
.
答案2
得分: 6
如果你真的想要检查一个goroutine的结果,你应该使用一个通道,像这样:
package main
import (
"fmt"
)
func main() {
// 在测试中
c := Hello()
if <-c != "done" {
fmt.Println("assert error")
}
// 不想检查结果
Hello()
}
func Hello() <-chan string {
c := make(chan string)
go func() {
fmt.Println("做一些事情")
c <- "done"
}()
return c
}
你可以在这里查看代码:https://play.golang.org/p/zUpNXg61Wn
英文:
If you really want to check the result of a goroutine, you should use a channel like so:
package main
import (
"fmt"
)
func main() {
// in test
c := Hello()
if <-c != "done" {
fmt.Println("assert error")
}
// not want to check result
Hello()
}
func Hello() <-chan string {
c := make(chan string)
go func() {
fmt.Println("do something")
c <- "done"
}()
return c
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论