测试使用全局变量的Go协程

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

Testing Go Routine with Global Variables

问题

我正在尝试在一个文件中测试以下方法(经过大量编辑以创建一个小样本):

app.go

  1. var fruit = ""
  2. func check(input string) bool {
  3. if input == "1" {
  4. go func() {
  5. fruit = "BANANA"
  6. time.Sleep(1 * time.Second)
  7. }()
  8. return true
  9. } else if fruit == "BANANA" {
  10. return true
  11. }
  12. return false
  13. }

app_test.go

  1. func TestInputs(t *testing.T) {
  2. res := check("1")
  3. res = check("2")
  4. if res != true {
  5. t.Errorf("got: %t, want: %t", res, true)
  6. }
  7. }

基本上,我希望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

  1. var fruit = ""
  2. func check(input string) bool {
  3. if input == "1" {
  4. go func() {
  5. fruit = "BANANA"
  6. time.Sleep(1 * time.Second)
  7. }()
  8. return true
  9. } else if fruit == "BANANA" {
  10. return true
  11. }
  12. return false
  13. }

app_test.go

  1. func TestInputs(t *testing.T) {
  2. res := check("1")
  3. res = check("2")
  4. if res != true {
  5. t.Errorf("got: %t, want: %t", res, true)
  6. }
  7. }

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.

huangapple
  • 本文由 发表于 2021年7月13日 16:31:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/68359021.html
匿名

发表评论

匿名网友

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

确定