英文:
Testing Go Routine with Global Variables
问题
我正在尝试在一个文件中测试以下方法(经过大量编辑以创建一个小样本):
app.go
var fruit = ""
func check(input string) bool {
if input == "1" {
go func() {
fruit = "BANANA"
time.Sleep(1 * time.Second)
}()
return true
} else if fruit == "BANANA" {
return true
}
return false
}
app_test.go
func TestInputs(t *testing.T) {
res := check("1")
res = check("2")
if res != true {
t.Errorf("got: %t, want: %t", res, true)
}
}
基本上,我希望res = check("2")
返回true,因为在之前的调用中fruit被设置为BANANA。这种情况是否可能?Go协程在这里并不太重要,但它是我程序功能的一部分,我不确定它是否会影响测试。
英文:
I'm trying to test the following method in a file (heavily edited to make a small sample):
app.go
var fruit = ""
func check(input string) bool {
if input == "1" {
go func() {
fruit = "BANANA"
time.Sleep(1 * time.Second)
}()
return true
} else if fruit == "BANANA" {
return true
}
return false
}
app_test.go
func TestInputs(t *testing.T) {
res := check("1")
res = check("2")
if res != true {
t.Errorf("got: %t, want: %t", res, true)
}
}
Essentially, I'd like res = check("2")
to return true, since fruit was set to BANANA in the previous call. Is this possible? The Go Routine shouldn't matter too much here - however it is part of my program's functionality and I'm not sure if it affects testing.
答案1
得分: 1
你在修改fruit
之前使用了time.Sleep()
,然而你的测试中没有使用任何东西来等待它。
一般来说,time.Sleep()
不是一个同步工具。即使在调用check()
之前在测试中插入了2秒的睡眠时间,这仍然是一个数据竞争:一个goroutine修改了fruit
,而另一个goroutine在没有同步的情况下读取它。这是未定义的行为。
使用适当的同步原语:锁、通道、等待组等。
英文:
You're using time.Sleep()
before changing fruit
, yet you don't use anything in your test to wait that.
In general time.Sleep()
is not a synchronization tool. Even if you'd insert a 2-second sleep in your test before calling check()
again, that's still a data race: one goroutine modifies fruit
, and another reads it without synchronization. This is undefined behavior.
Use proper synchronization primitives: that is: locks, channels, waitgroups etc.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论